如何用ImageMagick批量给指定矩形区域添加羽化提亮效果?
批量PNG图片区域提亮加羽化处理方案
环境信息
- 设备:2020款Mac Mini M1
- 操作系统:macOS Sonoma 14.5
- ImageMagick版本:7.0.10-0
需求说明
需要批量处理60张256×256像素的PNG图片,完成以下操作:
- 选中起始坐标(32,32)、尺寸192×192的矩形区域进行提亮
- 给该区域边缘添加**约64像素的羽化(feather)**效果
之前的尝试(效果不符合预期)
使用ChatGPT生成的zsh脚本进行处理,脚本内容如下:
#!/bin/zsh # Function to show usage function show_usage { echo "Usage: $0 --brightness value [--region x,y,width,height] [--feather radius] input_file" echo " --brightness value Adjust brightness (value between -1 and 1)" echo " --region x,y,width,height Apply adjustment only to the specified rectangular region" echo " --feather radius Feather (blur) the edges of the region (radius in pixels)" echo " input_file The image file to process" exit 1 } # Check that arguments are provided if [[ $# -lt 3 ]]; then show_usage fi # Parse arguments REGION="" FEATHER=0 while [[ $# -gt 0 ]]; do case "$1" in --brightness) BRIGHTNESS="$2" shift 2 ;; --region) REGION="$2" shift 2 ;; --feather) FEATHER="$2" shift 2 ;; *) INPUT_FILE="$1" shift ;; esac done # Check if input file exists if [[ ! -f "$INPUT_FILE" ]]; then echo "Input file does not exist: $INPUT_FILE" exit 1 fi # Calculate the brightness adjustment percentage for ImageMagick BRIGHTNESS_PERCENT=$(echo "scale=2; (1 + $BRIGHTNESS) * 100" | bc) # Create an output filename OUTPUT_FILE="${INPUT_FILE%.*}_brightness_feathered.${INPUT_FILE##*.}" # If region is specified, apply brightness only to that region if [[ -n "$REGION" ]]; then # Parse the region values IFS=',' read -r REGION_X REGION_Y REGION_WIDTH REGION_HEIGHT <<< "$REGION" echo "Applying brightness to region: ${REGION_X},${REGION_Y} ${REGION_WIDTH}x${REGION_HEIGHT}" echo "Feathering: ${FEATHER}px" magick "$INPUT_FILE" \ \( +clone -crop "${REGION_WIDTH}x${REGION_HEIGHT}+${REGION_X}+${REGION_Y}" \ -modulate "$BRIGHTNESS_PERCENT",100,100 -write mpr:region +delete \) \ \( -size "${REGION_WIDTH}x${REGION_HEIGHT}" xc:black -fill white \ -draw "rectangle 0,0 ${REGION_WIDTH},${REGION_HEIGHT}" \ -blur 0x"$FEATHER" -write mpr:mask +delete \) \ "$INPUT_FILE" -write mpr:original \ \( mpr:region mpr:mask -compose DstIn -composite \) \ -geometry +${REGION_X}+${REGION_Y} -compose Over -composite "$OUTPUT_FILE" else # Apply brightness adjustment to the entire image magick "$INPUT_FILE" -modulate "$BRIGHTNESS_PERCENT",100,100 "$OUTPUT_FILE" fi # Output result echo "Brightness adjusted image saved as: $OUTPUT_FILE"
测试命令:
% script.sh --brightness 0.6 --region 64,64,224,224 --feather 10 sample-1.png
正确的实现方案
原脚本的问题在于羽化遮罩的生成逻辑有误,大羽化半径下会丢失边缘过渡信息。以下是修正后的脚本,支持批量处理且效果符合预期:
修正后的zsh脚本
#!/bin/zsh # 显示使用说明 function show_usage { echo "使用方法: $0 --brightness 亮度值 [--region x,y,宽,高] [--feather 羽化半径] 输入文件/目录" echo " --brightness 亮度值 亮度调整范围(-1到1,正数提亮,负数变暗)" echo " --region x,y,宽,高 指定需要调整的矩形区域" echo " --feather 羽化半径 区域边缘羽化像素值" echo " 输入文件/目录 单个图片文件或包含PNG的目录" exit 1 } # 参数检查 if [[ $# -lt 3 ]]; then show_usage fi # 解析参数 REGION="32,32,192,192" # 默认使用需求中的区域 FEATHER=64 # 默认羽化64像素 BRIGHTNESS=0 INPUT_PATH="" while [[ $# -gt 0 ]]; do case "$1" in --brightness) BRIGHTNESS="$2" shift 2 ;; --region) REGION="$2" shift 2 ;; --feather) FEATHER="$2" shift 2 ;; *) INPUT_PATH="$1" shift ;; esac done # 计算ImageMagick需要的亮度百分比 BRIGHTNESS_PERCENT=$(echo "scale=2; (1 + $BRIGHTNESS) * 100" | bc) # 解析区域参数 IFS=',' read -r REG_X REG_Y REG_W REG_H <<< "$REGION" # 处理单个文件的函数 process_file() { local INPUT_FILE="$1" if [[ ! -f "$INPUT_FILE" ]]; then echo "文件不存在: $INPUT_FILE" return fi # 生成输出文件名 local OUTPUT_FILE="${INPUT_FILE%.*}_processed.${INPUT_FILE##*.}" echo "处理文件: $INPUT_FILE" echo "目标区域: $REG_X,$REG_Y ${REG_W}x${REG_H} | 羽化半径: $FEATHERpx | 亮度调整: $BRIGHTNESS" # 核心ImageMagick命令:修正遮罩生成逻辑 magick "$INPUT_FILE" \ # 提取并提亮目标区域 \( +clone -crop "${REG_W}x${REG_H}+${REG_X}+${REG_Y}" -modulate "$BRIGHTNESS_PERCENT",100,100 \) \ # 生成带羽化的遮罩:先创建扩展羽化半径的画布,避免模糊后边缘丢失 \( -size "$((REG_W + 2*FEATHER))x$((REG_H + 2*FEATHER))" xc:black \ -fill white -draw "rectangle $FEATHER,$FEATHER $((REG_W + FEATHER)),$((REG_H + FEATHER))" \ -blur 0x"$FEATHER" -crop "${REG_W}x${REG_H}+${FEATHER}+${FEATHER}" +repage \) \ # 将提亮区域与遮罩合成,得到带羽化边缘的提亮层 -compose DstIn -composite \ # 将提亮层叠加回原图对应位置 -geometry "+${REG_X}+${REG_Y}" -compose Over -composite \ "$OUTPUT_FILE" echo "处理完成,输出文件: $OUTPUT_FILE" } # 判断输入是文件还是目录,执行对应处理逻辑 if [[ -f "$INPUT_PATH" ]]; then process_file "$INPUT_PATH" elif [[ -d "$INPUT_PATH" ]]; then # 遍历目录下所有PNG文件 for file in "$INPUT_PATH"/*.png; do if [[ -f "$file" ]]; then process_file "$file" fi done else echo "输入路径无效: $INPUT_PATH" exit 1 fi
使用步骤
- 将脚本保存为
process_images.sh,赋予执行权限:
chmod +x process_images.sh
- 针对需求参数直接运行(默认匹配需求中的区域和羽化值):
./process_images.sh --brightness 0.6 /path/to/your/png-directory
- 如需自定义参数:
./process_images.sh --brightness 0.6 --region 32,32,192,192 --feather 64 /path/to/single-image.png
关键修正点
- 遮罩生成时先创建扩展羽化半径的画布,避免模糊后边缘过渡信息丢失,确保大羽化半径(64像素)效果自然
- 简化合成逻辑,减少不必要的内存对象操作,提升处理效率
- 增加目录批量处理功能,适配60张图片的处理需求
内容的提问来源于stack exchange,提问作者andrewz
相关产品推荐
相关产品推荐

