Python 批量旋转图片 90/180/270度并自动补白教程
用 Pillow 批量把文件夹里的图片顺时针或逆时针旋转任意角度,自动处理 EXIF 方向、旋转后留白填充,适合手机照片转正、扫描件批量调方向。
场景痛点
手机拍的照片导入电脑后方向是歪的,扫描件一批是横一批是竖,用看图软件一张张转方向累死人。更坑的是有些图本身在手机里看着正常,电脑打开却躺倒——这是 EXIF 方向标记没被正确识别。用 Python 一次性转正 + 按需旋转,批量输出到新目录。
用到的库
pip install Pillow
完整代码
# -*- coding: utf-8 -*-
# 批量旋转图片:先按 EXIF 转正,再统一旋转指定角度
import os
from PIL import Image, ImageOps
IMG_EXTS = {".jpg", ".jpeg", ".png", ".bmp", ".webp"}
# 常用角度:transpose 的快捷常量
ROTATE_MAP = {
90: Image.ROTATE_90, # 顺时针 90
180: Image.ROTATE_180,
270: Image.ROTATE_270, # 顺时针 270 = 逆时针 90
}
def batch_rotate(input_dir, output_dir, angle=90, fill=(255, 255, 255)):
"""angle 传 90/180/270;其他任意角度用 im.rotate"""
os.makedirs(output_dir, exist_ok=True)
for name in sorted(os.listdir(input_dir)):
ext = os.path.splitext(name)[1].lower()
if ext not in IMG_EXTS:
continue
try:
with Image.open(os.path.join(input_dir, name)) as im:
# 关键:先按 EXIF 标记转正,否则转了等于白转
im = ImageOps.exif_transpose(im)
if angle in ROTATE_MAP:
out = im.transpose(ROTATE_MAP[angle])
else:
# 任意角度旋转,expand=True 自动扩大画布
out = im.rotate(angle, expand=True, fillcolor=fill)
base, _ = os.path.splitext(name)
out.save(os.path.join(output_dir, base + ".jpg"),
quality=92)
print(f"旋转 {angle}° {name} -> {out.size}")
except Exception as e:
print(f"跳过 {name}: {e}")
if __name__ == "__main__":
# 把 ./raw 下所有图顺时针转 90 度,输出到 ./rotated
batch_rotate("./raw", "./rotated", angle=90)
代码讲解
ImageOps.exif_transpose(im)这一步非常关键:手机照片真实像素可能是横的,只是在 EXIF 里写了"查看时请逆时针转 90"。直接im.rotate会叠两层,越转越歪。先exif_transpose把像素按 EXIF 转正,后续旋转才准。- 90/180/270 这种整 90 度用
transpose(ROTATE_x),比rotate快且不损失画质,因为只是重排像素。 - 任意角度(比如 15°、45°)用
im.rotate(angle, expand=True, fillcolor=...):expand=True自动把画布扩大到能装下旋转后的图,fillcolor填四角留白的颜色。 - 输出统一
.jpg,避免 RGBA 透明图保存 JPG 出黑底。
运行结果
把拍歪或躺倒的照片放进 ./raw,运行后 ./rotated 里得到同名单图,方向已转正并按需要再转 90°。修改 angle=180 或 angle=45 即可批量换角度。
注意事项
- 不调用
exif_transpose直接旋转,是最常见的"越转越歪"坑,务必先转 EXIF。 - 任意角度旋转后图片边缘会有斜边锯齿,需要更高质量可加
resample=Image.BICUBIC。 - 旋转后宽高互换,文件大小也会变,属于正常现象。
- 扫描件如果是黑白,保存成 JPG 没问题;要无损就输出
.png。

更新时间:2026-09-14 20:20:47