批量调整图像色阶的脚本

wen 实用脚本 2
#!/usr/bin/env python3
"""
批量调整图像色阶脚本
功能:批量调整指定目录下所有图像的色阶(对比度和亮度)
支持格式:JPG, PNG, BMP, TIFF等
"""
import os
import argparse
from PIL import Image, ImageEnhance, ImageStat
import glob
def adjust_levels(image, black_point=0, white_point=255, gamma=1.0):
    """
    调整图像的色阶
    :param image: PIL Image对象
    :param black_point: 黑场阈值 (0-255)
    :param white_point: 白场阈值 (0-255)
    :param gamma: 伽马值
    :return: 调整后的PIL Image对象
    """
    # 转换为RGB模式(如果是RGBA则保留alpha通道)
    if image.mode == 'RGBA':
        # 分离通道
        r, g, b, a = image.split()
        # 调整RGB通道
        r = r.point(lambda x: _level_map(x, black_point, white_point, gamma))
        g = g.point(lambda x: _level_map(x, black_point, white_point, gamma))
        b = b.point(lambda x: _level_map(x, black_point, white_point, gamma))
        # 合并通道
        return Image.merge('RGBA', (r, g, b, a))
    else:
        # 确保图像为RGB模式
        if image.mode != 'RGB':
            image = image.convert('RGB')
        return image.point(lambda x: _level_map(x, black_point, white_point, gamma))
def _level_map(value, black_point, white_point, gamma):
    """
    单像素值的色阶映射函数
    """
    # 确保值在有效范围内
    value = max(0, min(255, value))
    # 映射到0-1范围
    normalized = (value - black_point) / (white_point - black_point)
    normalized = max(0, min(1, normalized))
    # 应用伽马校正
    if gamma != 1.0:
        normalized = pow(normalized, 1.0 / gamma)
    # 映射回0-255范围
    return int(normalized * 255)
def auto_levels(image):
    """
    自动调整色阶(拉伸到全范围)
    :param image: PIL Image对象
    :return: 调整后的PIL Image对象
    """
    # 获取图像的直方图统计
    if image.mode == 'RGBA':
        # 对于RGBA图像,使用RGB通道计算
        r, g, b, a = image.split()
        stats_r = ImageStat.Stat(r)
        stats_g = ImageStat.Stat(g)
        stats_b = ImageStat.Stat(b)
        # 找到所有通道中的最小和最大值
        min_val = min(stats_r.min[0], stats_g.min[0], stats_b.min[0])
        max_val = max(stats_r.max[0], stats_g.max[0], stats_b.max[0])
    else:
        if image.mode != 'RGB':
            image = image.convert('RGB')
        stats = ImageStat.Stat(image)
        min_val = min(stats.min)
        max_val = max(stats.max)
    # 添加1%的裁剪以避免极端值
    min_val = int(min_val * 1.01)
    max_val = int(max_val * 0.99)
    print(f"自动色阶: 黑场={min_val}, 白场={max_val}")
    return adjust_levels(image, black_point=min_val, white_point=max_val)
def batch_process(input_dir, output_dir, black_point=0, white_point=255, 
                  gamma=1.0, auto=False, quality=95, formats=None):
    """
    批量处理图像
    :param input_dir: 输入目录
    :param output_dir: 输出目录
    :param black_point: 黑场值
    :param white_point: 白场值
    :param gamma: 伽马值
    :param auto: 是否自动调整
    :param quality: JPEG输出质量
    :param formats: 处理的文件格式列表
    """
    # 支持的图像格式
    if formats is None:
        formats = ['*.jpg', '*.jpeg', '*.png', '*.bmp', '*.tiff', '*.tif', '*.webp']
    # 创建输出目录
    os.makedirs(output_dir, exist_ok=True)
    # 收集所有图像文件
    image_files = []
    for fmt in formats:
        pattern = os.path.join(input_dir, fmt)
        image_files.extend(glob.glob(pattern, recursive=True))
    # 也检查大写扩展名
    for fmt in formats:
        pattern = os.path.join(input_dir, fmt.upper())
        image_files.extend(glob.glob(pattern, recursive=True))
    # 去重
    image_files = list(set(image_files))
    if not image_files:
        print(f"在 {input_dir} 中没有找到图像文件")
        return
    print(f"找到 {len(image_files)} 个图像文件")
    # 处理每个图像
    for i, filepath in enumerate(image_files, 1):
        try:
            print(f"[{i}/{len(image_files)}] 处理中: {os.path.basename(filepath)}")
            # 打开图像
            with Image.open(filepath) as img:
                # 调整色阶
                if auto:
                    img_adjusted = auto_levels(img)
                else:
                    img_adjusted = adjust_levels(img, black_point, white_point, gamma)
                # 生成输出文件路径
                filename = os.path.basename(filepath)
                name, ext = os.path.splitext(filename)
                output_path = os.path.join(output_dir, f"{name}_adjusted{ext}")
                # 保存图像
                if ext.lower() in ['.jpg', '.jpeg']:
                    img_adjusted.save(output_path, quality=quality, optimize=True)
                elif ext.lower() == '.png':
                    img_adjusted.save(output_path, optimize=True)
                else:
                    img_adjusted.save(output_path)
                print(f"  保存至: {output_path}")
        except Exception as e:
            print(f"  处理 {filepath} 时出错: {e}")
    print(f"\n完成! 处理了 {len(image_files)} 个图像文件")
def main():
    parser = argparse.ArgumentParser(description='批量调整图像色阶')
    parser.add_argument('input_dir', help='输入图像目录')
    parser.add_argument('output_dir', help='输出图像目录')
    # 色阶参数
    parser.add_argument('--black', type=int, default=0, 
                       help='黑场值 (0-255,默认: 0)')
    parser.add_argument('--white', type=int, default=255, 
                       help='白场值 (0-255,默认: 255)')
    parser.add_argument('--gamma', type=float, default=1.0, 
                       help='伽马值 (默认: 1.0)')
    parser.add_argument('--auto', action='store_true', 
                       help='自动调整色阶(拉伸到全范围)')
    # 其他参数
    parser.add_argument('--quality', type=int, default=95, 
                       help='JPEG输出质量 (1-100,默认: 95)')
    parser.add_argument('--formats', nargs='+', 
                       default=['*.jpg', '*.jpeg', '*.png', '*.bmp', '*.tiff', '*.tif', '*.webp'],
                       help='处理的文件格式 (默认: 常见图像格式)')
    args = parser.parse_args()
    # 验证参数
    if not args.auto:
        if args.black < 0 or args.black > 255:
            print("错误: 黑场值必须在0-255之间")
            return
        if args.white < 0 or args.white > 255:
            print("错误: 白场值必须在0-255之间")
            return
        if args.black >= args.white:
            print("错误: 黑场值必须小于白场值")
            return
    if args.gamma <= 0:
        print("错误: 伽马值必须大于0")
        return
    batch_process(
        args.input_dir,
        args.output_dir,
        black_point=args.black,
        white_point=args.white,
        gamma=args.gamma,
        auto=args.auto,
        quality=args.quality,
        formats=args.formats
    )
if __name__ == '__main__':
    main()

使用方法

安装依赖

pip install pillow

基本用法

手动调整色阶:

批量调整图像色阶的脚本

python batch_levels.py ./input_images ./output_images --black 30 --white 220 --gamma 1.2

自动调整色阶:

python batch_levels.py ./input_images ./output_images --auto

仅处理PNG文件:

python batch_levels.py ./input_images ./output_images --auto --formats '*.png'

参数说明

参数 说明 默认值
input_dir 输入图像目录(必填)
output_dir 输出图像目录(必填)
--black 黑场值 (0-255) 0
--white 白场值 (0-255) 255
--gamma 伽马值 0
--auto 自动调整色阶 False
--quality JPEG输出质量 95
--formats 处理的文件格式 所有常见格式

示例

提高对比度:

python batch_levels.py ./photos ./enhanced --black 50 --white 200

提亮暗部:

python batch_levels.py ./photos ./brighter --gamma 1.5

自动优化:

python batch_levels.py ./photos ./auto_enhanced --auto

该脚本会保留原始图像格式,并在输出文件名后添加_adjusted后缀,对于RGBA图像(如透明PNG),会正确保留Alpha通道。

抱歉,评论功能暂时关闭!