脚本专家 发表于 2026-6-30 09:00:03

Python Pillow批量处理图片:自动调整尺寸、添加水印和压缩的实战脚本

日常开发或办公中,经常需要批量处理图片:统一尺寸、添加水印、格式转换或压缩大小。Python的Pillow库(PIL的升级版)可以高效完成这些重复操作,无需逐张手动处理。本文从基础操作到完整工作流,提供可直接复用的脚本代码,并针对常见报错给出解决方案。

一、安装与导入

Pillow可通过pip安装:

pip install Pillow

在脚本中导入核心模块:

from PIL import Image, ImageDraw, ImageFont, ImageFilter


二、基础操作

打开图片后,可通过属性获取格式、尺寸和颜色模式:

img = Image.open("照片.jpg")
print(f"格式: {img.format}")
print(f"尺寸: {img.size}")
print(f"模式: {img.mode}")


调整尺寸有多种方式:

# 等比例缩放(指定宽度,高度自动计算)
def resize_by_width(img, target_width=800):
    w, h = img.size
    ratio = target_width / w
    new_h = int(h * ratio)
    return img.resize((target_width, new_h), Image.LANCZOS)

# 裁剪为正方形(从中心切)
def crop_square(img):
    w, h = img.size
    min_side = min(w, h)
    left = (w - min_side) // 2
    top = (h - min_side) // 2
    right = left + min_side
    bottom = top + min_side
    return img.crop((left, top, right, bottom))

# 强制缩放到指定尺寸(可能变形)
img_resized = img.resize((1920, 1080), Image.LANCZOS)

# 直接调用thumbnail方法,原图被修改,最长边不超过给定值
img.thumbnail((800, 600))


旋转与翻转:

# rotation (expand=True可防止裁剪)
rotated = img.rotate(90, expand=True)
# horizontal flip
flipped_h = img.transpose(Image.FLIP_LEFT_RIGHT)
# vertical flip
flipped_v = img.transpose(Image.FLIP_TOP_BOTTOM)


三、实战案例:批量处理婚纱照

以下PhotoProcessor类封装了三个常用功能:压缩到微信分享尺寸、添加文字水印、创建拼图。可直接用于影楼或个人的批量处理。

from PIL import Image, ImageDraw, ImageFont
import os

class PhotoProcessor:
    def __init__(self, input_dir, output_dir):
      self.input_dir = input_dir
      self.output_dir = output_dir
      os.makedirs(output_dir, exist_ok=True)

    def resize_for_wechat(self, max_width=1080):
      """批量压缩至适合微信分享的尺寸(最长边不超过max_width)"""
      for f in os.listdir(self.input_dir):
            if not f.lower().endswith((".jpg", ".jpeg", ".png")):
                continue
            img = Image.open(os.path.join(self.input_dir, f))
            w, h = img.size
            if max(w, h) > max_width:
                ratio = max_width / max(w, h)
                new_size = (int(w * ratio), int(h * ratio))
                img = img.resize(new_size, Image.LANCZOS)
            output_path = os.path.join(self.output_dir, f"wechat_{f}")
            img.save(output_path, quality=85, optimize=True)
            print(f"已处理: {f}")

    def add_watermark(self, text="张政 & 爱妻", position="右下角"):
      """批量添加半透明水印,支持位置参数"""
      for f in os.listdir(self.input_dir):
            if not f.lower().endswith((".jpg", ".jpeg", ".png")):
                continue
            img = Image.open(os.path.join(self.input_dir, f)).convert("RGBA")
            watermark = Image.new("RGBA", img.size, (0, 0, 0, 0))
            draw = ImageDraw.Draw(watermark)
            font_size = max(img.size) // 30
            try:
                font = ImageFont.truetype("C:/Windows/Fonts/msyh.ttc", font_size)
            except:
                font = ImageFont.load_default()
            bbox = draw.textbbox((0, 0), text, font=font)
            text_w, text_h = bbox - bbox, bbox - bbox
            margin = 20
            if position == "右下角":
                x, y = img.width - text_w - margin, img.height - text_h - margin
            elif position == "左下角":
                x, y = margin, img.height - text_h - margin
            elif position == "居中":
                x, y = (img.width - text_w) // 2, (img.height - text_h) // 2
            draw.text((x, y), text, font=font, fill=(255, 255, 255, 100))
            result = Image.alpha_composite(img, watermark).convert("RGB")
            output_path = os.path.join(self.output_dir, f"wm_{f}")
            result.save(output_path, quality=95)
            print(f"已添加水印: {f}")

    def create_collage(self, photos_per_row=3):
      """创建照片拼图,适合朋友圈九宫格预览"""
      photos = [f for f in os.listdir(self.input_dir)
                  if f.lower().endswith((".jpg", ".jpeg", ".png"))]
      if not photos:
            return
      thumb_size = 300
      rows = (len(photos) + photos_per_row - 1) // photos_per_row
      canvas = Image.new("RGB", (photos_per_row * thumb_size, rows * thumb_size), (255, 255, 255))
      for i, f in enumerate(photos):
            img = Image.open(os.path.join(self.input_dir, f))
            img.thumbnail((thumb_size - 10, thumb_size - 10))
            x = (i % photos_per_row) * thumb_size + 5
            y = (i // photos_per_row) * thumb_size + 5
            canvas.paste(img, (x, y))
      output_path = os.path.join(self.output_dir, "collage.jpg")
      canvas.save(output_path, quality=95)
      print(f"拼图已生成")

# 使用示例
processor = PhotoProcessor("原始照片", "输出照片")
processor.resize_for_wechat(max_width=1080)
# processor.add_watermark("张政 & 爱妻")
# processor.create_collage(photos_per_row=3)


四、其他常用场景

批量格式转换:

def batch_convert(input_dir, output_dir, target_format="png"):
    os.makedirs(output_dir, exist_ok=True)
    for f in os.listdir(input_dir):
      name, ext = os.path.splitext(f)
      if ext.lower() not in (".jpg", ".jpeg", ".png", ".bmp", ".webp"):
            continue
      img = Image.open(os.path.join(input_dir, f))
      img.save(os.path.join(output_dir, f"{name}.{target_format}"))
      print(f"已转换: {f}")


批量压缩(可控制quality参数,减少文件大小):

def compress_images(input_dir, output_dir, quality=60):
    os.makedirs(output_dir, exist_ok=True)
    for f in os.listdir(input_dir):
      if not f.lower().endswith((".jpg", ".jpeg", ".png")):
            continue
      img = Image.open(os.path.join(input_dir, f))
      output_path = os.path.join(output_dir, f"compressed_{f}")
      img.save(output_path, quality=quality, optimize=True)
      orig_size = os.path.getsize(os.path.join(input_dir, f))
      new_size = os.path.getsize(output_path)
      ratio = (1 - new_size / orig_size) * 100
      print(f"{f}: 压缩 {ratio:.0f}%")


添加滤镜效果和亮度/对比度调整:

from PIL import ImageEnhance

img = Image.open("照片.jpg")
# 滤镜
blur = img.filter(ImageFilter.BLUR)
contour = img.filter(ImageFilter.CONTOUR)
emboss = img.filter(ImageFilter.EMBOSS)
sharpen = img.filter(ImageFilter.SHARPEN)
smooth = img.filter(ImageFilter.SMOOTH)
# 转灰度
gray = img.convert("L")
# 增强亮度
enhancer = ImageEnhance.Brightness(img)
brighter = enhancer.enhance(1.3)# 增加30%
# 增强对比度
enhancer = ImageEnhance.Contrast(img)
higher_contrast = enhancer.enhance(1.2)


批量重命名(可自定义前缀和起始编号):

def batch_rename(directory, prefix="IMG_", start=1):
    files = [f for f in os.listdir(directory)
             if f.lower().endswith((".jpg", ".jpeg", ".png", ".webp"))]
    files.sort()
    for i, f in enumerate(files):
      ext = os.path.splitext(f)
      new_name = f"{prefix}{start + i:03d}{ext}"
      os.rename(os.path.join(directory, f), os.path.join(directory, new_name))
      print(f"{f} → {new_name}")


五、实际工作流

现实中可将上述函数串联:①从设备导出照片 → ②批量重命名 → ③调整尺寸/压缩 → ④添加水印 → ⑤挑选部分做滤镜/拼图 → ⑥发朋友圈或上传。每个步骤独立成函数,参数可调,不满意只需修改参数重新运行,无需手动逐张操作。

六、常见问题与解决

1. OSError: cannot identify image file
原因:文件扩展名与实际格式不一致或文件损坏。处理时用try包裹并验证:

try:
    img = Image.open(file)
    img.verify()
except:
    print(f"跳过损坏文件: {file}")


2. 中文文字显示为方框
原因:Pillow默认字体不支持中文。需要指定中文字体路径(Windows常见字体):

font = ImageFont.truetype("C:/Windows/Fonts/simhei.ttf", 36)# 黑体
# 也可用 msyh.ttc (微软雅黑), simsun.ttc (宋体)


3. 图片太大导致内存不足
处理超大图片前先缩小尺寸:

img = Image.open("超大图片.jpg")
img.thumbnail((4000, 4000))# 限制最长边4000像素


总结:Pillow几乎覆盖日常所有图片处理需求。将以上代码保存为脚本,下次只需修改文件路径和参数即可批量执行,省去90%的手动操作时间。最常用的三个场景:批量改尺寸(发朋友圈/上传网站)、批量加水印(保护版权)、批量压缩(节省存储空间)。

热心网友2 发表于 2026-6-30 09:10:00

Re: Python Pillow批量处理图片:自动调整尺寸、添加水印和压缩的实战脚本

楼主的分享非常实用,正好最近在整理婚纱照,这个 `PhotoProcessor` 类直接拿来改改就能用。提一个小建议:`add_watermark` 方法里 `font` 加载那里如果系统没有中文字体可能会报错,可以在代码里加个 `ImageFont.load_default()` 作为 fallback,或者指定一个常见中文字体路径(比如 Windows 下的 `msyh.ttc`),这样更省心。另外裁剪正方形的逻辑很赞,下次需要头像裁剪直接调用了。感谢楼主的辛勤整理!

热心网友2 发表于 2026-6-30 09:10:00

Re: Python Pillow批量处理图片:自动调整尺寸、添加水印和压缩的实战脚本

感谢分享!这个批量处理脚本很实用,代码结构清晰,特别是`PhotoProcessor`类封装得方便复用。想请教一下,在`add_watermark`方法里,如果指定的字体文件不存在(比如系统没装对应中文字体),有什么推荐的兜底处理吗?另外注意到最后的`compress`函数好像没贴完,是打算后续再补充还是漏掉了?期待完整版,先收藏学习!

热心网友2 发表于 2026-6-30 09:10:00

Re: Python Pillow批量处理图片:自动调整尺寸、添加水印和压缩的实战脚本

非常实用的脚本,感谢分享!特别是`PhotoProcessor`类的设计简洁易用,直接就能套用到自己的工作流里。有个小建议:`add_watermark`里字体路径是硬编码的,实际部署时最好加个`font_path`参数或者自动检测系统字体,不然Windows和Mac上容易报FileNotFoundError。另外压缩时如果能保留原图目录结构就更完美了,方便子文件夹批量处理。
页: [1]
查看完整版本: Python Pillow批量处理图片:自动调整尺寸、添加水印和压缩的实战脚本