使用Python批量处理图片的实战指南

 更新时间:2026年03月27日 10:49:35   作者:站大爷IP  
当Word文档里的图片成了拦路虎,这种时候,Python就派上用场了,它不会抱怨重复劳动,也不会因为眼花点错图片,下面我们就来看看如何使用Python脚本实现批量处理图片吧

你有没有遇到过这样的场景:部门例会前,领导丢给你一个文件夹,里面是几十个Word文档,每个文档里都散落着好几张活动照片。你的任务很简单——把所有图片提取出来,统一调整尺寸,再按照特定的顺序塞进一个新的报告文档里。

听起来不难,对吧?但当你打开第一个文档,一张张右键另存为,再调整尺寸,再复制粘贴到新文档……重复几十次之后,你会开始怀疑人生。手头的工作变成了纯粹的体力劳动,而且只要有一个环节出错,就得从头再来。

这种时候,Python就派上用场了。它不会抱怨重复劳动,也不会因为眼花点错图片。我花了两个小时写了一小段脚本,把原本一整天的手工活压缩成了三分钟。今天就把这段经历和代码拆开来讲,希望能帮你摆脱同样的困境。

准备工作:装好工具箱

在动手之前,得先把需要用到的工具装上。Python的好处就是有大量的第三方库,专门解决这类问题。这次我们需要三个帮手:

pip install python-docx pillow

python-docx是我们操作Word文档的主力。它可以读取文档里的文字、表格、图片,也能从头创建新的文档或者修改现有的文档。Pillow是Python图像处理库,负责调整图片尺寸、转换格式这些活儿。

安装完成之后,在代码开头把这些库引进来:

from docx import Document
from docx.shared import Inches, Cm
from PIL import Image
import io
import os

InchesCm是用来设置图片大小的单位,io帮我们处理内存里的图片数据,os负责管理文件和文件夹路径。

从Word文档里“捞”出图片

Word文档和图片的关系,比看起来要复杂一点。你可能会想,图片不就是放在文档里的吗?但当我们用代码去读取时,需要找到正确的“门路”。

每个.docx文件其实是个压缩包,图片被藏在内部的media文件夹里,通过XML关系与文档内容关联。python-docx提供了一个方法,可以顺着这个关系把图片提取出来。

下面这段代码能遍历一个文件夹里所有的Word文档,把每张图片提取出来,按照“文档名_图片序号.jpg”的格式保存:

def extract_images_from_docx(folder_path):
    # 遍历文件夹里所有docx文件
    for filename in os.listdir(folder_path):
        if not filename.endswith('.docx'):
            continue
            
        doc_path = os.path.join(folder_path, filename)
        doc = Document(doc_path)
        
        # 准备一个文件夹存放提取出的图片
        img_folder = os.path.join(folder_path, filename.replace('.docx', '_images'))
        if not os.path.exists(img_folder):
            os.makedirs(img_folder)
        
        img_count = 0
        # 遍历文档中的所有段落
        for paragraph in doc.paragraphs:
            for run in paragraph.runs:
                # 在run的XML中查找图片标记
                blip = run._r.find('.//a:blip', 
                    namespaces={'a': 'http://schemas.openxmlformats.org/drawingml/2006/main'})
                if blip is not None:
                    embed_id = blip.get('{http://schemas.openxmlformats.org/officeDocument/2006/relationships}embed')
                    if embed_id and embed_id in run.part.related_parts:
                        image_part = run.part.related_parts[embed_id]
                        img_stream = io.BytesIO(image_part.blob)
                        img = Image.open(img_stream)
                        
                        img_count += 1
                        img_path = os.path.join(img_folder, f'image_{img_count}.jpg')
                        img.save(img_path, 'JPEG')
                        print(f'已提取: {img_path}')
        
        print(f'{filename} 处理完成,共提取 {img_count} 张图片')

这段代码的核心是那个看起来很复杂的XML查找。简单解释一下:Word文档的内部结构是用XML描述的,图片会被标记为<a:blip>元素,通过embed属性关联到实际的图片数据。我们把图片数据从内存里读出来,用Pillow打开,再保存到本地,就完成了提取。

批量处理图片:统一尺寸和格式

提取出来的图片可能大小不一,有的横版有的竖版,如果直接塞进文档里会很难看。我们可以统一调整尺寸,让它们都变成一样的宽度,高度按比例自动缩放。

def resize_images(image_folder, output_width=500):
    # 获取文件夹里所有图片
    image_files = [f for f in os.listdir(image_folder) 
                   if f.endswith(('.jpg', '.jpeg', '.png'))]
    
    for img_file in image_files:
        img_path = os.path.join(image_folder, img_file)
        img = Image.open(img_path)
        
        # 计算等比例缩放后的高度
        original_width, original_height = img.size
        new_height = int(output_width * original_height / original_width)
        
        # 使用高质量缩放算法
        resized_img = img.resize((output_width, new_height), Image.Resampling.LANCZOS)
        
        # 覆盖原图或者保存为新文件
        resized_img.save(img_path, quality=95)
        print(f'已调整尺寸: {img_file} -> {output_width}x{new_height}')

这里用了Image.Resampling.LANCZOS,这是Pillow里质量最高的缩放算法,虽然慢一点,但效果最好。如果你的图片数量特别多,可以考虑用Image.Resampling.BILINEAR换速度。

把图片塞回新文档

图片都准备好了,现在要把它们按照顺序插进一个新的Word文档里。python-docx插入图片的方法很直观,用add_picture就行:

def create_photo_report(image_folder, output_path='report.docx'):
    # 创建新文档
    doc = Document()
    
    # 添加标题
    doc.add_heading('活动照片集锦', 0)
    
    # 获取所有图片文件并排序
    image_files = sorted([f for f in os.listdir(image_folder) 
                          if f.endswith(('.jpg', '.jpeg', '.png'))])
    
    for img_file in image_files:
        img_path = os.path.join(image_folder, img_file)
        
        # 添加一个段落,放图片说明
        doc.add_heading(img_file.replace('_', ' ').replace('.jpg', ''), level=2)
        
        # 插入图片,宽度设为6英寸,高度自动缩放
        doc.add_picture(img_path, width=Inches(6))
        
        # 添加一点留白
        doc.add_paragraph()
    
    doc.save(output_path)
    print(f'报告已生成: {output_path}')

add_picturewidth参数可以接受InchesCmPt单位。如果你想让图片按固定高度插入,也可以用height参数。只指定一个维度时,另一个维度会自动等比缩放,不用自己算。

进阶技巧:在指定位置插入图片

有些时候,光是把图片堆在文档末尾不够用。你可能需要把图片插到某个段落后边,或者放到表格的某个单元格里。

在段落里插图片,关键是先拿到那个段落,然后在它的run里添加:

# 假设我们要在文档的第一个段落之后插入图片
doc = Document('existing.docx')
target_paragraph = doc.paragraphs[0]  # 获取第一个段落
run = target_paragraph.add_run()       # 在段落中创建一个新run
run.add_picture('image.jpg', width=Inches(3))  # 插入图片

在表格里插图片也类似,先定位到单元格,再操作:

table = doc.add_table(rows=2, cols=2)
cell = table.cell(0, 0)  # 第一行第一列
paragraph = cell.paragraphs[0]
run = paragraph.add_run()
run.add_picture('image.jpg', width=Cm(5))

需要注意的是,python-docx对图片位置的精确控制能力有限,没办法像手动操作那样任意拖拽到指定坐标。如果对排版有很高要求,可以先通过代码把图片插入到位,再用Word手动微调。

处理那些烦人的“坑”

实际应用中总会遇到一些意外情况,比如文档里有浮动图片、文档是旧的.doc格式等等。这里说几个常见坑的应对方法。

浮动图片提取不到:上面那种通过段落查找的方法只能提取“嵌入型”图片。如果文档里有浮在文字上方的图片,需要更底层的操作。可以用python-docxpart.related_parts遍历所有资源,找到图片类型就保存。一个更简单但笨一点的办法是:先把文档另存为.docx,用压缩软件打开,直接去word/media文件夹里复制图片。

遇到.doc格式:python-docx只支持.docx,处理不了旧版.doc文件。可以先用win32com库在Windows上转换,或者用LibreOffice的命令行工具批量转换。如果只是偶尔遇到,手动转一下可能更快。

图片插入后变形:这通常是因为给图片设置了固定的宽高,但比例和原图不一致。解决办法是只设置一个维度,让另一个维度自动缩放。如果必须指定两个维度,可以先用Pillow读取原图尺寸,再手动计算缩放后的宽高。

写在最后

回到开头的场景,当你再次面对几十个需要处理图片的Word文档时,你可以选择继续手工操作,也可以写一段脚本,然后去泡杯咖啡,等着它帮你把一切做完。

Python自动化最大的魅力就在这里——它不是为了炫技,而是为了把我们从重复劳动里解放出来,去做那些真正需要思考和创造的事情。这次我们只用了python-docxPillow两个库,但你能做的事情远不止提取和插入图片。

想想你日常工作里那些“反复做、费时间、有规律”的事情,很可能都可以用类似的方式自动化。批量生成合同、整理数据报表、统一修改文档格式……这些场景里,Python都能成为你的得力助手。

到此这篇关于使用Python批量处理图片的实战指南的文章就介绍到这了,更多相关Python批量处理图片内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Django Auth用户认证组件实现代码

    Django Auth用户认证组件实现代码

    这篇文章主要介绍了Django Auth用户认证组件实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • Python3.5迭代器与生成器用法实例分析

    Python3.5迭代器与生成器用法实例分析

    这篇文章主要介绍了Python3.5迭代器与生成器用法,结合实例形式分析了Python3.5列表生成式、生成器、迭代器等相关原理与用法,需要的朋友可以参考下
    2019-04-04
  • python实现生成Word、docx文件的方法分析

    python实现生成Word、docx文件的方法分析

    这篇文章主要介绍了python实现生成Word、docx文件的方法,结合实例形式分析了Python使用docx模块操作word文件与docx文件的相关实现技巧,需要的朋友可以参考下
    2019-08-08
  • python如何按顺序批量修改文件名

    python如何按顺序批量修改文件名

    这篇文章主要介绍了python如何按顺序批量修改文件名问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • 用Python生成HTML表格的方法示例

    用Python生成HTML表格的方法示例

    这篇文章主要介绍了用Python生成HTML表格的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • 自制python包并通过pip上传pypi

    自制python包并通过pip上传pypi

    这篇文章主要为大家介绍了自己制作python包并通过pip上传pypi实现过程详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • Python实现将内容写入文件的五种方法总结

    Python实现将内容写入文件的五种方法总结

    本篇带你详细看一下python将内容写入文件的方法以及细节,主要包括write()方法、writelines() 方法、print() 函数、使用 csv 模块、使用 json 模块,需要的可以参考一下
    2023-04-04
  • 使用Python的Treq on Twisted来进行HTTP压力测试

    使用Python的Treq on Twisted来进行HTTP压力测试

    这篇文章主要介绍了使用Python的Treq on Twisted来进行HTTP压力测试,基于Python中的Twisted框架,需要的朋友可以参考下
    2015-04-04
  • Python Django 实现简单注册功能过程详解

    Python Django 实现简单注册功能过程详解

    这篇文章主要介绍了Python Django 实现简单注册功能过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-07-07
  • python单下划线和双下划线属性区别

    python单下划线和双下划线属性区别

    本文主要介绍了python单下划线和双下划线属性区别,主要在于命名规范、访问意图、名称改写机制以及子类继承中的表现,感兴趣的可以了解一下
    2025-12-12

最新评论