当Word文档里的图片成了“拦路虎”:用Python批量处理图片的实战指南

简介: 本文分享用Python批量处理Word文档图片的实战方案:利用python-docx提取图片、Pillow统一调整尺寸与格式,并自动插入新报告文档。附完整代码与常见问题(如浮动图、.doc格式)解决方案,助你3分钟完成原本一整天的手工活。

当Word文档里的图片成了“拦路虎”:用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(imgfolder, 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(imgfile.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(00)  # 第一行第一列
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都能成为你的得力助手。


目录
相关文章
|
2月前
|
人工智能 缓存 文字识别
Python驱动的PDF信息提取与结构化输出:从文本到表格的全流程解析
本文详解Python处理PDF的三大场景:文本提取(PyPDF2/pdfplumber)、扫描件OCR(Tesseract+pdf2image)、表格结构化(Camelot/tabula),结合真实案例演示精准提取与自动化输出,助力合同、发票等业务数据高效数字化。(239字)
287 1
|
1月前
|
存储 人工智能 关系型数据库
OpenClaw怎么可能没痛点?用RDS插件来释放OpenClaw全部潜力
OpenClaw插件是深度介入Agent生命周期的扩展机制,提供24个钩子,支持自动注入知识、持久化记忆等被动式干预。相比Skill/Tool,插件可主动在关键节点(如对话开始/结束)执行逻辑,适用于RAG增强、云化记忆等高级场景。
904 56
OpenClaw怎么可能没痛点?用RDS插件来释放OpenClaw全部潜力
|
22天前
|
人工智能 弹性计算 数据可视化
部署OpenClaw有哪些成本?附OpenClaw低成本部署指南
OpenClaw(“养龙虾”)是一款开源AI代理框架,可自动化文件处理、工作流与消息管理。本文详解其部署成本:软件免费,云服务器低至68元/年,阿里云百炼新用户享7000万Token免费额度,并提供一键图形化部署指南。
628 32
|
20天前
|
存储 消息中间件 关系型数据库
(二)走进阿里云实时计算Flink版-场景案例篇
阿里云实时计算Flink版产品负责人黄鹏程(马格)介绍:基于Apache Flink打造的企业级全托管实时计算平台,支持批流一体、湖仓融合、实时风控与AI推理等场景,助力满帮、车企等客户降本增效35%,SLA达99.9%。
410 3
(二)走进阿里云实时计算Flink版-场景案例篇
|
20天前
|
人工智能 安全 API
|
24天前
|
Web App开发 供应链 数据可视化
快递地图轨迹-快递物流轨迹地图-物流信息可视化API接口的运用
快递物流轨迹地图API,支持顺丰、中通、圆通等600+快递公司,在APP中直观展示实时物流轨迹,提升用户体验。提供标准化接口,含运单查询、手机号校验、排序等参数,返回高可用地图链接。
451 2
快递地图轨迹-快递物流轨迹地图-物流信息可视化API接口的运用
|
1月前
|
JSON 监控 测试技术
微服务接口设计全解:RESTful/RPC 规范、兼容方案与生产级实战
本文系统阐述微服务接口设计规范,涵盖RESTful与RPC两大体系:明确接口作为行为契约的本质,提出语义清晰、兼容稳定、高性能等五大设计目标;详解URI设计、HTTP方法/状态码、请求响应体等RESTful规范,并给出完整代码实例;解析RPC的契约优先、幂等性、序列化等核心要求;对比二者差异,提供选型指南与灰度发布、多版本共存等生产级兼容方案,助力构建高可靠微服务架构。
394 4
|
1月前
|
Arthas 人工智能 Java
我们做了比你更懂 Java 的 AI-Agent -- Arthas Agent
Arthas Agent 是基于阿里开源Java诊断工具Arthas的AI智能助手,支持自然语言提问,自动匹配排障技能、生成安全可控命令、循证推进并输出结构化报告,大幅降低线上问题定位门槛。
1061 64
我们做了比你更懂 Java 的 AI-Agent -- Arthas Agent
|
1月前
|
人工智能 安全 前端开发
阿里开源 Team 版 OpenClaw,5分钟完成本地安装
HiClaw 是 OpenClaw 的升级版,通过引入 Manager Agent 架构和分布式设计,解决了 OpenClaw 在安全性、多任务协作、移动端体验、记忆管理等方面的核心痛点。
1933 60
阿里开源 Team 版 OpenClaw,5分钟完成本地安装

热门文章

最新文章

下一篇
开通oss服务