使用Python+Pillow批量裁剪图片的三种常见场景与解决方法

 更新时间:2026年06月22日 09:16:14   作者:detayun  
这篇文章介绍了使用Python的Pillow库进行批量图片裁剪的方法,覆盖固定尺寸、居中正方形及精确坐标三种场景,并提供相应代码示例,并解决了一些常见问题,需要的朋友可以参考下

为什么要批量裁剪图片?

做电商要统一主图尺寸、社交媒体头像要裁成正方形、证件照需要固定比例……手动一张张裁,几十张就够你喝两杯咖啡了。

用Python + Pillow,几行代码就能批量搞定。这篇博客覆盖最常用的3个场景,每个都给可运行代码。

场景一:固定尺寸裁剪(左上角裁剪)

最简单粗暴的方式:把所有图片裁成统一的宽×高。

from PIL import Image
import os

def crop_fixed_size(input_dir, output_dir, width, height):
    os.makedirs(output_dir, exist_ok=True)
    
    for filename in os.listdir(input_dir):
        if not filename.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp', '.webp')):
            continue
        
        img_path = os.path.join(input_dir, filename)
        img = Image.open(img_path)
        
        # 左上角裁剪
        cropped = img.crop((0, 0, width, height))
        cropped.save(os.path.join(output_dir, filename))
        print(f"{filename} → {width}x{height}")

# 使用:裁成 800x600
crop_fixed_size(r'D:\原图', r'D:\裁剪后', 800, 600)

如果原图比目标尺寸小,会报错。下面的"居中裁剪"可以解决这个问题。

场景二:居中裁剪成正方形(最常用)

社交媒体头像、商品主图,基本都要正方形。这个方法会自动居中裁剪,不会拉伸变形。

from PIL import Image
import os

def crop_center_square(input_dir, output_dir, size):
    os.makedirs(output_dir, exist_ok=True)
    
    for filename in os.listdir(input_dir):
        if not filename.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp', '.webp')):
            continue
        
        img_path = os.path.join(input_dir, filename)
        img = Image.open(img_path)
        
        # 取最小边作为裁剪尺寸,保证不会切掉内容
        min_side = min(img.width, img.height)
        left = (img.width - min_side) // 2
        top = (img.height - min_side) // 2
        right = left + min_side
        bottom = top + min_side
        
        cropped = img.crop((left, top, right, bottom))
        
        # 再缩放到目标尺寸(可选)
        cropped = cropped.resize((size, size), Image.LANCZOS)
        
        cropped.save(os.path.join(output_dir, filename))
        print(f"{filename} → {size}x{size}")

# 使用:裁成 500x500 正方形
crop_center_square(r'D:\照片', r'D:\头像', 500)

效果对比

原图居中裁剪左上角裁剪
1200×800 横图✅ 保留中间主体❌ 只保留左上角
800×1200 竖图✅ 保留中间主体❌ 只保留左上角

场景三:按坐标批量裁剪(精确控制)

有些场景需要精确裁剪某个区域,比如证件照只取头部、截图只取特定区域。

from PIL import Image
import os

def crop_by_coordinates(input_dir, output_dir, coords):
    """
    coords: (left, top, right, bottom)
    例如:(100, 50, 400, 400) 表示从(100,50)到(400,400)的矩形区域
    """
    os.makedirs(output_dir, exist_ok=True)
    
    left, top, right, bottom = coords
    crop_width = right - left
    crop_height = bottom - top
    
    for filename in os.listdir(input_dir):
        if not filename.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp', '.webp')):
            continue
        
        img_path = os.path.join(input_dir, filename)
        img = Image.open(img_path)
        
        # 判断原图是否够大
        if img.width < right or img.height < bottom:
            print(f"⚠️ {filename} 尺寸不足,跳过")
            continue
        
        cropped = img.crop((left, top, right, bottom))
        cropped.save(os.path.join(output_dir, filename))
        print(f"{filename} → 裁剪区域 {coords}")

# 使用:裁剪左上角 (100, 50) 到 (600, 550) 的区域
crop_by_coordinates(r'D:\截图', r'D:\裁剪后', (100, 50, 600, 550))

进阶:批量裁剪 + 加水印(一气呵成)

裁剪完直接加上水印,电商场景特别实用。

from PIL import Image, ImageDraw, ImageFont
import os

def crop_and_watermark(input_dir, output_dir, size, watermark_text):
    os.makedirs(output_dir, exist_ok=True)
    
    for filename in os.listdir(input_dir):
        if not filename.lower().endswith(('.jpg', '.jpeg', '.png')):
            continue
        
        img_path = os.path.join(input_dir, filename)
        img = Image.open(img_path)
        
        # 居中裁剪
        min_side = min(img.width, img.height)
        left = (img.width - min_side) // 2
        top = (img.height - min_side) // 2
        cropped = img.crop((left, top, left + min_side, top + min_side))
        cropped = cropped.resize((size, size), Image.LANCZOS)
        
        # 加水印
        draw = ImageDraw.Draw(cropped)
        font = ImageFont.truetype("simhei.ttf", int(size * 0.08))  # Windows自带黑体
        
        text_bbox = draw.textbbox((0, 0), watermark_text, font=font)
        text_width = text_bbox[2] - text_bbox[0]
        x = (size - text_width) // 2
        y = size - int(size * 0.1)
        
        draw.text((x, y), watermark_text, fill=(255, 255, 255, 128), font=font)
        
        cropped.save(os.path.join(output_dir, filename), quality=95)
        print(f"{filename} → 裁剪+水印完成")

# 使用
crop_and_watermark(r'D:\商品图', r'D:\成品', 800, '店铺名称')

如果是Mac/Linux,字体路径改成 /System/Library/Fonts/Supplemental/Arial Unicode.ttf 或安装中文字体。

常见问题速查

问题解决方案
图片有透明通道,保存后变黑底cropped.convert('RGB') 转成RGB再保存
裁剪后图片模糊resize()Image.LANCZOS 而不是默认的 Image.BILINEAR
批量处理速度慢考虑用 concurrent.futures.ThreadPoolExecutor 多线程处理
需要保留EXIF信息piexif 库,或 pillow-heif 处理HEIC格式

总结

批量裁剪图片的核心就三步:

  1. 打开图片Image.open()
  2. 裁剪区域img.crop((左, 上, 右, 下))
  3. 保存结果img.save()

上面的代码覆盖了固定尺寸、居中正方形、精确坐标三种最常见需求,复制过去改一下路径就能跑。

如果你需要更复杂的操作(比如按人脸自动裁剪、批量加圆角),评论区说,我接着写。

以上就是使用Python+Pillow批量裁剪图片的三种常见场景与解决方法的详细内容,更多关于Python Pillow批量裁剪图片的资料请关注脚本之家其它相关文章!

相关文章

  • Python range函数之生成器函数的示例

    Python range函数之生成器函数的示例

    这篇文章主要介绍了Python range函数之生成器函数的示例,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-12-12
  • 详解pandas中MultiIndex和对象实际索引不一致问题

    详解pandas中MultiIndex和对象实际索引不一致问题

    这篇文章主要介绍了详解pandas中MultiIndex和对象实际索引不一致问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-07-07
  • 深入探讨Python进行代码重构的详细指南

    深入探讨Python进行代码重构的详细指南

    代码重构是在不改变代码外在行为的前提下,对代码内部结构进行改进的过程,是软件开发过程中的一项核心技能,下面小编就来和大家深入介绍一下代码重构吧
    2025-08-08
  • 使用setup.py安装python包和卸载python包的方法

    使用setup.py安装python包和卸载python包的方法

    这篇文章主要介绍了使用setup.py安装python包和卸载python包的方法,大家参考使用吧
    2013-11-11
  • Python yield的使用详解

    Python yield的使用详解

    您可能听说过,带有 yield 的函数在 Python 中被称之为、generator(生成器),何谓 generator ?我们先抛开 generator,以一个常见的编程题目来展示 yield 的概念
    2021-10-10
  • python抓取文件夹的所有文件

    python抓取文件夹的所有文件

    这篇文章主要为大家详细介绍了python抓取文件夹的所有文件,包括子文件夹和子文件夹的文件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-02-02
  • PyCharm使用matplotlib报MatplotlibDeprecationWarning问题解决办法

    PyCharm使用matplotlib报MatplotlibDeprecationWarning问题解决办法

    这篇文章主要给大家介绍了关于PyCharm使用matplotlib报MatplotlibDeprecationWarning问题解决的相关资料,主要是 matplotlib版本过高导致的,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2023-06-06
  • Python发送email的3种方法

    Python发送email的3种方法

    这篇文章主要介绍了Python发送email的3种方法,本文讲解了使用登录邮件服务器方法、调用sendmail命令、使用smtp服务来发送三种方法,需要的朋友可以参考下
    2015-04-04
  • Python标准库之加密模块详解

    Python标准库之加密模块详解

    这篇文章主要为大家详细介绍了Python标准库中加密模块的相关知识,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的小伙伴可以了解一下
    2023-07-07
  • 在Python中使用第三方模块的教程

    在Python中使用第三方模块的教程

    这篇文章主要介绍了在Python中使用第三方模块的教程,是Python学习当中的基础知识,需要的朋友可以参考下
    2015-04-04

最新评论