You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

使用步骤

  1. 将脚本保存为process_images.sh,赋予执行权限:
chmod +x process_images.sh
  1. 针对需求参数直接运行(默认匹配需求中的区域和羽化值):
./process_images.sh --brightness 0.6 /path/to/your/png-directory
  1. 如需自定义参数:
./process_images.sh --brightness 0.6 --region 32,32,192,192 --feather 64 /path/to/single-image.png

关键修正点

  • 遮罩生成时先创建扩展羽化半径的画布,避免模糊后边缘过渡信息丢失,确保大羽化半径(64像素)效果自然
  • 简化合成逻辑,减少不必要的内存对象操作,提升处理效率
  • 增加目录批量处理功能,适配60张图片的处理需求

内容的提问来源于stack exchange,提问作者andrewz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 14:49:54