使用 Python 和 Pillow 给装修现场照片批量打时间水印并拼成施工日记九宫格(中文路径/EXIF 坑)

 更新时间:2026年11月03日 09:41:22   作者:麦序子  
本文介绍使用Python和Pillow对装修现场照片进行批量处理:读取EXIF或文件时间戳生成日期水印,自动纠正EXIF旋转方向,解决中文路径、中文乱码及图像变形问题,感兴趣的朋友跟随小编一起看看吧

装修施工动辄两三个月,现场照片一天拍几十张,月底想整理成"施工日记"发给业主,最头疼两件事:一是照片不知道是哪天拍的,二是几百张图散着没法看。本文用纯 Python(Pillow)写一个本地小工具:批量给照片叠加「日期+工种」水印,再按 3×3 拼成九宫格日报图,全程不联网、双击可用。我会重点讲三个实战大坑——中文路径、EXIF 旋转、水印中文乱码,都是我踩过的。

一、整体思路

  1. 扫描某个目录下所有 .jpg/.png;
  2. 读取拍摄时间(优先 EXIF,没有就退回文件修改时间);
  3. 在右下角叠加半透明文字水印(日期 + 自定义工种标签);
  4. 把当天照片每 9 张拼一张九宫格,输出到 日报/ 目录。

依赖只有一个:pip install Pillow。

二、中文路径:别用字符串硬拼

Windows 下路径带中文(如 D:/装修照片/水电/),最稳的做法是全程用 pathlib.Path,它内部用 os.fspath 正确转码,避免 open() 报 FileNotFoundError: [Errno 2]。

from pathlib import Path
root = Path(r"D:/装修照片/水电")
imgs = sorted(p for p in root.glob("*") if p.suffix.lower() in (".jpg", ".jpeg", ".png"))

坑 1:别用 os.listdir() 再手动拼字符串,容易在 open 时因为 GBK 编码炸掉。用 Path 一步到位。

三、EXIF 旋转:手机拍的图可能"横着读"

很多手机照片在 Windows 看图正常,但 Pillow 打开却是旋转 90° 的——因为旋转信息存在 EXIF 的 Orientation 标签里,看图软件会自动纠正,Pillow 默认不纠正。批量处理前务必统一纠正:

from PIL import Image, ExifTags
def fix_orientation(img):
    try:
        exif = img._getexif()
        if not exif:
            return img
        for k, v in exif.items():
            if ExifTags.TAGS.get(k) == "Orientation":
                if v == 3:
                    img = img.rotate(180, expand=True)
                elif v == 6:
                    img = img.rotate(-90, expand=True)
                elif v == 8:
                    img = img.rotate(90, expand=True)
    except Exception:
        pass
    return img

坑 2:不纠正直接拼图,九宫格里有一半图是歪的。这个纠正必须放在 resize 之前。

四、水印中文乱码:指定字体文件

Pillow 的 ImageDraw.text 默认字体不带中文字形,写中文会成方块。必须显式指定一个中文字体 ttf:

from PIL import ImageDraw, ImageFont
font = ImageFont.truetype("C:/Windows/Fonts/msyh.ttc", 36)  # 微软雅黑

坑 3:truetype 的路径同样可能含中文,用 Path 传入即可。字体大小要按图尺寸缩放,别写死像素。

叠加水印的函数:

def add_watermark(img, text):
    draw = ImageDraw.Draw(img, "RGBA")
    w, h = img.size
    # 半透明黑底条
    draw.rectangle([(w-360, h-60), (w, h)], fill=(0, 0, 0, 120))
    draw.text((w-350, h-48), text, font=font, fill=(255, 255, 255, 230))
    return img

注意:水印要在「缩略图」上打,而不是原图画质上,既能看清又不破坏原图。

五、拼九宫格

把 9 张缩略图贴到一张大图:

def make_grid(images, cols=3, thumb=360, gap=8):
    rows = (len(images) + cols - 1) // cols
    grid = Image.new("RGB", (cols*thumb + (cols+1)*gap, rows*thumb + (rows+1)*gap), (240,240,240))
    for i, im in enumerate(images):
        im = fix_orientation(im).convert("RGB")
        im.thumbnail((thumb, thumb))
        r, c = divmod(i, cols)
        x = gap + c*(thumb+gap)
        y = gap + r*(thumb+gap)
        grid.paste(im, (x, y))
    return grid

thumbnail 会等比例缩放且不拉伸变形,比手动 resize 安全。

六、按天归档

用拍摄日期分组,每天生成一张日报图:

from collections import defaultdict
from datetime import datetime
groups = defaultdict(list)
for p in imgs:
    d = get_shoot_date(p)            # 读 EXIF 或 mtime
    groups[d.strftime("%Y-%m-%d")].append(p)
for day, paths in groups.items():
    day_imgs = [add_watermark(fix_orientation(Image.open(p)), f"{day} 水电") for p in paths[:9]]
    grid = make_grid(day_imgs)
    grid.save(out_dir / f"{day}_施工日记.png")

七、小结与避坑清单

  • 路径一律用 pathlib.Path,避开中文编码雷区;
  • 开图先 fix_orientation 纠正 EXIF 旋转,再缩放/拼图;
  • 中文水印必须 truetype 指定字体,否则方块乱码;
  • 水印打在缩略图上,原图保持干净;
  • thumbnail 等比缩放不变形,比硬编码 resize 稳。

把这套脚本跑起来,每天收工前 30 秒就能生成一张可发给业主的施工日报,比零散发图专业太多。完整可运行脚本和字体适配细节见我整理的本地工具包文档。

本文示例代码已在 Python 3.11 + Pillow 10 实测通过;字体路径请按本机实际位置调整。

到此这篇关于用 Python 和 Pillow 给装修现场照片批量打时间水印并拼成施工日记九宫格(中文路径/EXIF 坑)的文章就介绍到这了,更多相关Python Pillow对装修现场照片批量处理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python处理字符串的常用函数实例总结

    Python处理字符串的常用函数实例总结

    在数据分析中,特别是文本分析中,字符处理需要耗费极大的精力,因而了解字符处理对于数据分析而言,也是一项很重要的能力,这篇文章主要给大家介绍了关于Python处理字符串的常用函数,需要的朋友可以参考下
    2021-11-11
  • Python和OpenCV库实现识别人物出现并锁定

    Python和OpenCV库实现识别人物出现并锁定

    本文主要介绍了Python和OpenCV库实现识别人物出现并锁定,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • Windows下用py2exe将Python程序打包成exe程序的教程

    Windows下用py2exe将Python程序打包成exe程序的教程

    这篇文章主要介绍了Windows下用py2exe将Python程序打包成exe程序的教程,文中主要针对Python3.x版本进行说明,需要的朋友可以参考下
    2015-04-04
  • Python输出华丽分割线的方式大全

    Python输出华丽分割线的方式大全

    在 Python 编程中,有时候我们需要为日志、输出结果或者调试信息添加一些分割线,方便视觉上的区分,这篇文章将介绍几种常见的方法和一些创意的分割线设计,帮助你让代码输出更具美感和个性化,需要的朋友可以参考下
    2025-08-08
  • python实现发送图片到打印机进行打印

    python实现发送图片到打印机进行打印

    这篇文章主要为大家详细介绍了如何使用python实现发送图片到打印机进行打印,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2025-10-10
  • 基于Pyinstaller打包Python程序并压缩文件大小

    基于Pyinstaller打包Python程序并压缩文件大小

    这篇文章主要介绍了基于Pyinstaller打包Python程序并压缩文件大小,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • Python中常用的8种字符串操作方法

    Python中常用的8种字符串操作方法

    这篇文章主要介绍了Python中常用的8种字符串操作方法,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-05-05
  • pytorch中DataLoader()过程中遇到的一些问题

    pytorch中DataLoader()过程中遇到的一些问题

    这篇文章主要介绍了pytorch中DataLoader()过程中遇到的一些问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-05-05
  • 利用Python绘制随机游走图的详细过程

    利用Python绘制随机游走图的详细过程

    随机游走(random walk)也称随机漫步,随机行走等,是以随机的方式采取连续步骤的过程,下面这篇文章主要给大家介绍了关于利用Python绘制随机游走图的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-02-02
  • 解决PyQt5 无边框后窗口的移动问题

    解决PyQt5 无边框后窗口的移动问题

    这篇文章主要介绍了解决PyQt5 无边框后窗口的移动问题,具有很好的参考价值,希望对大家有所帮助,一起跟随小编过来看看吧
    2021-03-03

最新评论