几百张照片要统一尺寸?一张张用PS改到崩溃?Python让你一键搞定所有图片处理!
一、先看这个真实场景
李老师每次活动后都要干这些事:
- 春游拍了200张学生照片,要统一压缩到1MB以内发家长群
- 要把所有照片从JPG转成PNG格式(学校网站要求)
- 最后按学生姓名重命名(“张三.jpg”、“李四.jpg”)
以前他:
- 打开PS → 批处理 → 设置动作 → 跑脚本(太复杂) ✓
- 用在线工具 → 上传200张 → 等半小时 → 下载 → 广告弹窗烦死人 ✓
一整天没了!
二、Python的“图片工厂”魔法
今天教你用Python批量处理图片,三行代码搞定上面所有事:
from PIL import Imageimport os# 1. 批量调整尺寸(统一宽度800像素)for 文件名 in os.listdir('原始照片'):if 文件名.endswith('.jpg'): 图片 = Image.open(os.path.join('原始照片', 文件名)) 新尺寸 = 800, int(图片.height * 800 / 图片.width) # 按比例缩放 图片.resize(新尺寸).save(os.path.join('处理后', 文件名))# 2. 批量添加文字水印from PIL import ImageDraw, ImageFontfor 文件名 in os.listdir('处理后'): 图片 = Image.open(os.path.join('处理后', 文件名)).convert('RGBA')# 创建透明图层画水印 水印 = Image.new('RGBA', 图片.size, (255,255,255,0)) 画板 = ImageDraw.Draw(水印) 字体 = ImageFont.truetype('simhei.ttf', 30) # 需要黑体字体文件 画板.text((50, 50), 'XX学校春游留念', fill=(255,255,255,128), font=字体)# 合并原图和水印 结果 = Image.alpha_composite(图片, 水印) 结果.convert('RGB').save(os.path.join('带水印', 文件名))print("✅ 所有图片处理完成!")
看懂了吗?
全程免费,不用安装PS,不泄露隐私!
三、分解“魔法”:每步在干什么?
3.1 第一步:安装需要的库
pip install Pillow
Pillow 是 Python 最强大的图片处理库,PIL 的升级版。
3.2 调整图片尺寸详解
图片 = Image.open('照片.jpg')新尺寸 = (800, 600)图片.resize(新尺寸).save('新照片.jpg')
- resize((宽, 高)):直接指定宽高,但图片会变形
原宽, 原高 = 图片.size新宽 = 800新高 = int(原高 * 新宽 / 原宽)图片.resize((新宽, 新高)).save('新照片.jpg')
3.3 添加文字水印详解
from PIL import ImageDraw, ImageFont图片 = Image.open('照片.jpg').convert('RGBA') # 转为RGBA模式,支持透明水印层 = Image.new('RGBA', 图片.size, (255,255,255,0)) # 透明图层画板 = ImageDraw.Draw(水印层)# 设置字体(需要系统中存在的字体文件)字体 = ImageFont.truetype('simhei.ttf', 30) # 黑体,字号30画板.text((50, 50), '水印文字', fill=(255,255,255,128), font=字体)# 合并原图和水印层结果 = Image.alpha_composite(图片, 水印层)结果.convert('RGB').save('带水印的照片.jpg')(50, 50):文字左上角坐标fill=(255,255,255,128):白色,透明度128(0-255)Image.alpha_composite():叠加两个RGBA图片
注意:如果图片是JPG(没有透明通道),需要先 convert('RGBA'),合并后再转回RGB保存。
3.4 批量转换格式
for 文件名 in os.listdir('原始照片'):if 文件名.endswith('.jpg'): 图片 = Image.open(os.path.join('原始照片', 文件名)) 新文件名 = 文件名.replace('.jpg', '.png') 图片.save(os.path.join('转换后', 新文件名))
四、自己动手试试!
4.1 第一步:创建测试文件夹和照片
随便找几张图片,放到新建的 原始照片 文件夹里。如果没有,可以自己画几张。
4.2 第二步:批量缩放图片到统一宽度
import osfrom PIL import Image输入文件夹 = '原始照片'输出文件夹 = '处理后'os.makedirs(输出文件夹, exist_ok=True)目标宽度 = 800for 文件名 in os.listdir(输入文件夹):if 文件名.lower().endswith(('.jpg', '.jpeg', '.png')): 输入路径 = os.path.join(输入文件夹, 文件名) 图片 = Image.open(输入路径)# 等比例缩放 原宽, 原高 = 图片.size 新宽 = 目标宽度 新高 = int(原高 * 新宽 / 原宽) 图片缩放 = 图片.resize((新宽, 新高)) 输出路径 = os.path.join(输出文件夹, 文件名) 图片缩放.save(输出路径)print(f'已处理:{文件名}')print('✅ 批量缩放完成!')
4.3 第三步:添加水印
在 处理后 文件夹基础上继续:
from PIL import Image, ImageDraw, ImageFont水印文件夹 = '带水印'os.makedirs(水印文件夹, exist_ok=True)try: 字体 = ImageFont.truetype('simhei.ttf', 30) # Windows自带黑体except: 字体 = ImageFont.load_default() # 如果没有,用默认字体(不支持中文)for 文件名 in os.listdir(输出文件夹): 输入路径 = os.path.join(输出文件夹, 文件名) 图片 = Image.open(输入路径).convert('RGBA')# 创建水印层 水印层 = Image.new('RGBA', 图片.size, (255,255,255,0)) 画板 = ImageDraw.Draw(水印层) 画板.text((50, 50), 'XX学校春游留念', fill=(255,255,255,128), font=字体)# 合并 结果 = Image.alpha_composite(图片, 水印层) 输出路径 = os.path.join(水印文件夹, 文件名) 结果.convert('RGB').save(输出路径)print(f'已添加水印:{文件名}')print('✅ 水印添加完成!')
五、办公实战1:批量添加图片边框(让照片更美观)
from PIL import Image, ImageOps输入文件夹 = '原始照片'输出文件夹 = '带边框'os.makedirs(输出文件夹, exist_ok=True)边框大小 = 20 # 像素边框颜色 = 'lightblue'for 文件名 in os.listdir(输入文件夹):if 文件名.lower().endswith(('.jpg', '.jpeg', '.png')): 图片 = Image.open(os.path.join(输入文件夹, 文件名)) 带边框 = ImageOps.expand(图片, border=边框大小, fill=边框颜色) 带边框.save(os.path.join(输出文件夹, 文件名))print(f'已添加边框:{文件名}')print('✅ 所有图片已添加边框!')
六、办公实战2:自动生成缩略图(用于网站)
输入文件夹 = '原始照片'输出文件夹 = '缩略图'os.makedirs(输出文件夹, exist_ok=True)缩略图尺寸 = (200, 200)for 文件名 in os.listdir(输入文件夹):if 文件名.lower().endswith(('.jpg', '.jpeg', '.png')): 图片 = Image.open(os.path.join(输入文件夹, 文件名)) 图片.thumbnail(缩略图尺寸) # 保持比例的缩略图 图片.save(os.path.join(输出文件夹, 文件名))print(f'已生成缩略图:{文件名}')print('✅ 缩略图生成完成!')
七、进阶技巧:按拍摄日期自动整理照片
结合第18天学的日期处理,我们可以把照片按拍摄日期归档:
import osfrom PIL import Imagefrom PIL.ExifTags import TAGSfrom datetime import datetimedef 获取拍摄日期(图片路径):"""从照片EXIF中提取拍摄日期""" try: 图片 = Image.open(图片路径) exif = 图片._getexif()if exif:for 标签, 值 in exif.items(): 标签名 = TAGS.get(标签, 标签)if 标签名 == 'DateTimeOriginal':return datetime.strptime(值, '%Y:%m:%d %H:%M:%S') except: passreturn None输入文件夹 = '原始照片'for 文件名 in os.listdir(输入文件夹): 文件路径 = os.path.join(输入文件夹, 文件名) 拍摄日期 = 获取拍摄日期(文件路径)if 拍摄日期: 年份 = 拍摄日期.year 月份 = 拍摄日期.month 目标文件夹 = os.path.join(输入文件夹, str(年份), f'{月份:02d}月') os.makedirs(目标文件夹, exist_ok=True) os.rename(文件路径, os.path.join(目标文件夹, 文件名))print(f'移动 {文件名} -> {年份}年{月份}月')print('✅ 照片按拍摄日期整理完成!')
八、重点总结:今天你学会了什么?
✅ 核心技能
- ImageDraw.text() - 添加文字水印
- Image.thumbnail() - 生成缩略图
✅ 办公应用场景
✅ 效率对比
九、今日挑战:动手做!
任务1:批量裁剪图片(统一裁成正方形)
# 提示:计算最短边,从中心裁剪正方形,再用.resize统一尺寸
任务2:批量添加Logo水印(把公司Logo图片贴在角落)
# 提示:用 .paste() 方法,注意Logo需要调整大小和透明度
任务3:自动识别模糊照片并删除
# 提示:可以用拉普拉斯方差判断清晰度(需要安装 cv2 或使用PIL的滤波器)
十、明日预告
明天学终极自动化:搭建你的个人办公机器人!
真正的“办公自动化大师”,从明天开始!
回复「Py-Day23」获取今日挑战题解及本文完整代码。
评论区作业:晒出你处理过的图片,或者分享你遇到的坑!👇