131 lines
4.3 KiB
Bash
Executable File
131 lines
4.3 KiB
Bash
Executable File
#!/bin/zsh
|
||
setopt null_glob
|
||
|
||
# 从环境变量或参数获取配置
|
||
INPUT_FILE="${INPUT_FILE:-$1}"
|
||
OUTPUT_FILE="${OUTPUT_FILE:-$2}"
|
||
MODELPATH="${MODELPATH:-./models}"
|
||
MODELNAME="${MODELNAME:-ultramix-balanced-4x}"
|
||
BIN_PATH="${BIN_PATH:-./bin/mac/upscayl-bin}"
|
||
TARGET_WIDTH=4320
|
||
TARGET_HEIGHT=7680
|
||
FORMAT="jpg"
|
||
THREADS="4:8:4"
|
||
TARGET_SIZE=$((10 * 1024 * 1024)) # 10MB
|
||
MAX_SIZE=$((20 * 1024 * 1024)) # 20MB
|
||
|
||
# 检查输入参数
|
||
if [ -z "$INPUT_FILE" ] || [ -z "$OUTPUT_FILE" ]; then
|
||
echo "错误: 需要指定输入和输出文件路径"
|
||
echo "用法: $0 <输入文件> <输出文件>"
|
||
echo "或者设置环境变量 INPUT_FILE 和 OUTPUT_FILE"
|
||
exit 1
|
||
fi
|
||
|
||
if [ ! -f "$INPUT_FILE" ]; then
|
||
echo "错误: 输入文件不存在: $INPUT_FILE"
|
||
exit 1
|
||
fi
|
||
|
||
echo "===== 开始处理单张图片 ====="
|
||
echo "输入文件: $INPUT_FILE"
|
||
echo "输出文件: $OUTPUT_FILE"
|
||
echo "模型路径: $MODELPATH"
|
||
echo "模型名称: $MODELNAME"
|
||
echo "二进制文件: $BIN_PATH"
|
||
|
||
# 确保输出目录存在
|
||
output_dir=$(dirname "$OUTPUT_FILE")
|
||
mkdir -p "$output_dir"
|
||
|
||
base=$(basename "$INPUT_FILE")
|
||
compress=10 # 0为无压缩,100为最大压缩
|
||
try=1
|
||
|
||
echo "\n==== 开始处理: $base ===="
|
||
echo "输入文件: $INPUT_FILE"
|
||
echo "输出文件: $OUTPUT_FILE"
|
||
echo "模型: $MODELNAME, 模型路径: $MODELPATH"
|
||
echo "格式: $FORMAT"
|
||
|
||
# 获取原图宽高
|
||
read orig_w orig_h <<< $(sips -g pixelWidth -g pixelHeight "$INPUT_FILE" 2>/dev/null | awk '/pixelWidth/ {w=$2} /pixelHeight/ {h=$2} END{print w,h}')
|
||
if [ "$orig_w" -lt "$orig_h" ]; then
|
||
short=$orig_w
|
||
long=$orig_h
|
||
else
|
||
short=$orig_h
|
||
long=$orig_w
|
||
fi
|
||
echo "DEBUG: orig_w=$orig_w, orig_h=$orig_h, short=$short, long=$long"
|
||
|
||
scale1=$(echo "scale=8; 4320/$short" | bc)
|
||
scale2=$(echo "scale=8; 7680/$long" | bc)
|
||
echo "DEBUG: scale1=$scale1, scale2=$scale2"
|
||
|
||
# 取scale1和scale2的最大值
|
||
scale=$(echo "$scale1 > $scale2" | bc -l)
|
||
if [ "$scale" -eq 1 ]; then
|
||
use_scale=$scale1
|
||
else
|
||
use_scale=$scale2
|
||
fi
|
||
use_scale=$(printf "%f" "$use_scale")
|
||
echo "DEBUG: use_scale=$use_scale"
|
||
|
||
# 保证不缩小
|
||
scale_cmp=$(echo "$use_scale > 1" | bc -l)
|
||
echo "DEBUG: scale_cmp=$scale_cmp"
|
||
if [ "$scale_cmp" -eq 1 ]; then
|
||
target_w=$(awk -v w="$orig_w" -v s="$use_scale" 'BEGIN{printf "%d", w*s+0.5}')
|
||
target_h=$(awk -v h="$orig_h" -v s="$use_scale" 'BEGIN{printf "%d", h*s+0.5}')
|
||
echo "原图分辨率: ${orig_w}x${orig_h}, 目标分辨率: ${target_w}x${target_h} (短边≥4320, 长边≥7680)"
|
||
else
|
||
target_w=$orig_w
|
||
target_h=$orig_h
|
||
echo "原图分辨率: ${orig_w}x${orig_h}, 已满足短边≥4320且长边≥7680,无需放大"
|
||
fi
|
||
|
||
# 处理图片,循环调整压缩率直到满足大小要求
|
||
while true; do
|
||
echo "尝试第 $try 次: compress=$compress"
|
||
upscale_cmd="\"$BIN_PATH\" -i \"$INPUT_FILE\" -o \"$OUTPUT_FILE\" -f $FORMAT -m \"$MODELPATH\" -n $MODELNAME -r \"${target_w}x${target_h}\" -c $compress -j $THREADS -v"
|
||
echo "执行命令: $upscale_cmd"
|
||
eval $upscale_cmd
|
||
|
||
if [ ! -f "$OUTPUT_FILE" ]; then
|
||
echo "$base: 未生成图片,compress=$compress"
|
||
echo "处理失败"
|
||
exit 1
|
||
fi
|
||
|
||
size=$(stat -f%z "$OUTPUT_FILE")
|
||
res=$(sips -g pixelWidth -g pixelHeight "$OUTPUT_FILE" 2>/dev/null | awk '/pixelWidth|pixelHeight/ {print $2}' | xargs | sed 's/ /x/')
|
||
echo "$base: compress=$compress, size=${size} bytes, 分辨率=${res}"
|
||
|
||
if [ $size -le $MAX_SIZE ] || [ $compress -ge 100 ]; then
|
||
echo "$base: 满足大小要求,最终 compress=$compress"
|
||
break
|
||
fi
|
||
|
||
# compress 每次递增10,最大不超过100
|
||
compress=$((compress + 10))
|
||
[ $compress -gt 100 ] && compress=100
|
||
try=$((try+1))
|
||
[ $try -gt 10 ] && echo "$base: 达到最大尝试次数,停止调整" && break
|
||
done
|
||
|
||
echo "\n===== 处理完成 ====="
|
||
if [ -f "$OUTPUT_FILE" ]; then
|
||
input_size=$(stat -f%z "$INPUT_FILE")
|
||
output_size=$(stat -f%z "$OUTPUT_FILE")
|
||
input_res=$(sips -g pixelWidth -g pixelHeight "$INPUT_FILE" 2>/dev/null | awk '/pixelWidth|pixelHeight/ {print $2}' | xargs | sed 's/ /x/')
|
||
output_res=$(sips -g pixelWidth -g pixelHeight "$OUTPUT_FILE" 2>/dev/null | awk '/pixelWidth|pixelHeight/ {print $2}' | xargs | sed 's/ /x/')
|
||
|
||
echo "输入: $(basename "$INPUT_FILE") - ${input_size} bytes, ${input_res}"
|
||
echo "输出: $(basename "$OUTPUT_FILE") - ${output_size} bytes, ${output_res}"
|
||
echo "处理成功完成!"
|
||
else
|
||
echo "处理失败:未生成输出文件"
|
||
exit 1
|
||
fi |