Python自动化图片与PDF批量处理:从Pillow到OCR的完整方案
在实际工作中我们经常会遇到需要批量处理图片或PDF文档的场景。无论是产品图片统一尺寸、添加水印还是将多个PDF合并、拆分或转换格式手动操作不仅效率低下还容易出错。虽然Photoshop等专业工具提供了批量处理功能但对于非设计人员来说学习成本较高且需要付费使用。本文将介绍如何使用Python和开源工具构建一套完整的图片批量处理和PDF处理流程实现从图片预处理到PDF生成的全自动化。这套方案特别适合需要定期处理大量图片和文档的运营人员、内容创作者和办公人员无需编程基础也能快速上手。1. 环境准备与工具选择1.1 核心工具介绍图片批量处理主要使用Pillow库这是Python图像处理的标准库支持多种图像格式的读写和基本操作。PDF处理使用PyPDF2和reportlab库前者用于PDF的拆分、合并等操作后者用于将图片转换为PDF。对于更复杂的PDF处理需求还可以考虑pdfplumber库它能够提取PDF中的文本、表格等结构化信息。如果需要进行OCR识别可以集成pytesseract库。1.2 环境配置步骤首先确保系统已安装Python 3.7及以上版本。然后通过pip安装所需依赖pip install Pillow PyPDF2 reportlab pdfplumber pytesseract如果是Windows系统还需要安装Tesseract OCR引擎# 通过chocolatey安装 choco install tesseract # 或手动下载安装包 # 下载地址https://github.com/UB-Mannheim/tesseract/wikiLinux系统可以通过包管理器安装# Ubuntu/Debian sudo apt-get install tesseract-ocr # CentOS/RHEL sudo yum install tesseract1.3 项目目录结构建议按以下结构组织项目文件image-pdf-processor/ ├── src/ │ ├── image_processor.py # 图片处理核心模块 │ ├── pdf_processor.py # PDF处理核心模块 │ └── utils.py # 工具函数 ├── input/ # 输入文件目录 │ ├── images/ # 待处理图片 │ └── pdfs/ # 待处理PDF ├── output/ # 输出文件目录 ├── config/ # 配置文件目录 └── requirements.txt # 依赖列表2. 图片批量处理实现2.1 基本图片操作函数首先实现图片处理的基础功能包括尺寸调整、格式转换、水印添加等from PIL import Image, ImageDraw, ImageFont import os class ImageProcessor: def __init__(self, input_dir, output_dir): self.input_dir input_dir self.output_dir output_dir os.makedirs(output_dir, exist_okTrue) def resize_images(self, target_size(800, 600), keep_aspectTrue): 批量调整图片尺寸 for filename in os.listdir(self.input_dir): if filename.lower().endswith((.png, .jpg, .jpeg)): input_path os.path.join(self.input_dir, filename) output_path os.path.join(self.output_dir, filename) with Image.open(input_path) as img: if keep_aspect: img.thumbnail(target_size, Image.Resampling.LANCZOS) else: img img.resize(target_size, Image.Resampling.LANCZOS) img.save(output_path) print(f已处理: {filename}) def convert_format(self, target_formatJPEG, quality85): 批量转换图片格式 for filename in os.listdir(self.input_dir): if filename.lower().endswith((.png, .jpg, .jpeg, .bmp)): input_path os.path.join(self.input_dir, filename) name_without_ext os.path.splitext(filename)[0] output_filename f{name_without_ext}.{target_format.lower()} output_path os.path.join(self.output_dir, output_filename) with Image.open(input_path) as img: if img.mode in (RGBA, P): img img.convert(RGB) img.save(output_path, formattarget_format, qualityquality) print(f已转换: {filename} - {output_filename})2.2 高级图片处理功能除了基本操作还可以实现更复杂的功能如批量添加水印、图片压缩优化等def add_watermark(self, watermark_text, font_size36, opacity128): 批量添加文字水印 try: font ImageFont.truetype(arial.ttf, font_size) except: font ImageFont.load_default() for filename in os.listdir(self.input_dir): if filename.lower().endswith((.png, .jpg, .jpeg)): input_path os.path.join(self.input_dir, filename) output_path os.path.join(self.output_dir, filename) with Image.open(input_path) as img: # 创建水印层 watermark Image.new(RGBA, img.size, (0, 0, 0, 0)) draw ImageDraw.Draw(watermark) # 计算水印位置右下角 bbox draw.textbbox((0, 0), watermark_text, fontfont) text_width bbox[2] - bbox[0] text_height bbox[3] - bbox[1] position (img.width - text_width - 20, img.height - text_height - 20) # 绘制水印 draw.text(position, watermark_text, fontfont, fill(255, 255, 255, opacity)) # 合并图片和水印 if img.mode ! RGBA: img img.convert(RGBA) result Image.alpha_composite(img, watermark) if output_path.lower().endswith(.jpg) or output_path.lower().endswith(.jpeg): result result.convert(RGB) result.save(output_path) print(f已添加水印: {filename}) def optimize_images(self, quality85, optimizeTrue): 批量优化图片质量 for filename in os.listdir(self.input_dir): if filename.lower().endswith((.png, .jpg, .jpeg)): input_path os.path.join(self.input_dir, filename) output_path os.path.join(self.output_dir, filename) with Image.open(input_path) as img: # 转换为RGB模式JPEG不支持透明度 if img.mode in (RGBA, P): img img.convert(RGB) save_kwargs {quality: quality, optimize: optimize} if filename.lower().endswith(.png): # PNG优化参数 img.save(output_path, optimizeoptimize) else: # JPEG优化参数 img.save(output_path, **save_kwargs) original_size os.path.getsize(input_path) new_size os.path.getsize(output_path) reduction (original_size - new_size) / original_size * 100 print(f优化完成: {filename} - 大小减少: {reduction:.1f}%)3. PDF处理功能实现3.1 PDF基本操作PDF处理主要包括合并、拆分、旋转页面等基础功能import PyPDF2 from reportlab.lib.pagesizes import letter, A4 from reportlab.pdfgen import canvas import io class PDFProcessor: def __init__(self, input_dir, output_dir): self.input_dir input_dir self.output_dir output_dir os.makedirs(output_dir, exist_okTrue) def merge_pdfs(self, output_filenamemerged.pdf): 合并多个PDF文件 merger PyPDF2.PdfMerger() pdf_files [f for f in os.listdir(self.input_dir) if f.lower().endswith(.pdf)] pdf_files.sort() # 按文件名排序 for pdf_file in pdf_files: pdf_path os.path.join(self.input_dir, pdf_file) merger.append(pdf_path) print(f已添加: {pdf_file}) output_path os.path.join(self.output_dir, output_filename) with open(output_path, wb) as output_file: merger.write(output_file) merger.close() print(fPDF合并完成: {output_filename}) def split_pdf(self, filename, pages_per_split1): 按页拆分PDF文件 input_path os.path.join(self.input_dir, filename) with open(input_path, rb) as file: pdf_reader PyPDF2.PdfReader(file) total_pages len(pdf_reader.pages) for start_page in range(0, total_pages, pages_per_split): end_page min(start_page pages_per_split, total_pages) pdf_writer PyPDF2.PdfWriter() for page_num in range(start_page, end_page): pdf_writer.add_page(pdf_reader.pages[page_num]) output_filename f{os.path.splitext(filename)[0]}_pages_{start_page1}-{end_page}.pdf output_path os.path.join(self.output_dir, output_filename) with open(output_path, wb) as output_file: pdf_writer.write(output_file) print(f已生成: {output_filename})3.2 图片转PDF功能将处理好的图片批量转换为PDF文档def images_to_pdf(self, pdf_filenameimages.pdf, page_sizeA4): 将图片批量转换为PDF image_files [f for f in os.listdir(self.input_dir) if f.lower().endswith((.png, .jpg, .jpeg))] image_files.sort() if not image_files: print(未找到图片文件) return output_path os.path.join(self.output_dir, pdf_filename) # 创建PDF c canvas.Canvas(output_path, pagesizepage_size) page_width, page_height page_size for image_file in image_files: image_path os.path.join(self.input_dir, image_file) try: with Image.open(image_path) as img: # 计算图片在页面中的合适尺寸 img_width, img_height img.size scale min((page_width - 100) / img_width, (page_height - 100) / img_height) new_width img_width * scale new_height img_height * scale # 居中显示 x (page_width - new_width) / 2 y (page_height - new_height) / 2 # 添加新页面并绘制图片 c.showPage() c.drawImage(image_path, x, y, new_width, new_height) print(f已添加图片: {image_file}) except Exception as e: print(f处理图片 {image_file} 时出错: {e}) c.save() print(fPDF生成完成: {pdf_filename}) def extract_images_from_pdf(self, pdf_filename): 从PDF中提取图片 import fitz # PyMuPDF input_path os.path.join(self.input_dir, pdf_filename) doc fitz.open(input_path) for page_num in range(len(doc)): page doc.load_page(page_num) image_list page.get_images() for img_index, img in enumerate(image_list): xref img[0] base_image doc.extract_image(xref) image_bytes base_image[image] image_ext base_image[ext] output_filename f{os.path.splitext(pdf_filename)[0]}_page{page_num1}_img{img_index1}.{image_ext} output_path os.path.join(self.output_dir, output_filename) with open(output_path, wb) as image_file: image_file.write(image_bytes) print(f已提取图片: {output_filename}) doc.close()4. 完整工作流整合4.1 配置文件管理使用JSON配置文件来管理处理参数便于重复使用和修改{ image_processing: { input_dir: ./input/images, output_dir: ./output/images, resize: { enabled: true, width: 800, height: 600, keep_aspect: true }, watermark: { enabled: true, text: Confidential, font_size: 36, opacity: 128 }, optimize: { enabled: true, quality: 85 } }, pdf_processing: { input_dir: ./input/pdfs, output_dir: ./output/pdfs, merge_enabled: false, split_enabled: true, pages_per_split: 1 } }4.2 主程序实现创建主程序来协调整个处理流程import json from src.image_processor import ImageProcessor from src.pdf_processor import PDFProcessor class BatchProcessor: def __init__(self, config_fileconfig/settings.json): with open(config_file, r, encodingutf-8) as f: self.config json.load(f) def process_images(self): 执行图片批量处理 img_config self.config[image_processing] processor ImageProcessor(img_config[input_dir], img_config[output_dir]) if img_config[resize][enabled]: size (img_config[resize][width], img_config[resize][height]) processor.resize_images(size, img_config[resize][keep_aspect]) if img_config[watermark][enabled]: watermark_config img_config[watermark] processor.add_watermark( watermark_config[text], watermark_config[font_size], watermark_config[opacity] ) if img_config[optimize][enabled]: processor.optimize_images(img_config[optimize][quality]) def process_pdfs(self): 执行PDF处理 pdf_config self.config[pdf_processing] processor PDFProcessor(pdf_config[input_dir], pdf_config[output_dir]) if pdf_config[merge_enabled]: processor.merge_pdfs() if pdf_config[split_enabled]: pdf_files [f for f in os.listdir(pdf_config[input_dir]) if f.lower().endswith(.pdf)] for pdf_file in pdf_files: processor.split_pdf(pdf_file, pdf_config[pages_per_split]) def run_full_workflow(self): 执行完整工作流 print(开始图片处理...) self.process_images() print(开始PDF处理...) self.process_pdfs() print(所有处理完成) if __name__ __main__: processor BatchProcessor() processor.run_full_workflow()5. 常见问题与解决方案5.1 图片处理常见问题问题1处理大图片时内存不足现象处理高分辨率图片时程序崩溃或报内存错误。解决方案使用流式处理分块读取图片数据from PIL import ImageFile ImageFile.LOAD_TRUNCATED_IMAGES True # 设置最大图像像素限制 Image.MAX_IMAGE_PIXELS None # 或设置一个合理的上限问题2图片格式兼容性问题现象某些特殊格式的图片无法打开或处理。解决方案添加格式验证和异常处理def safe_image_open(image_path): try: with Image.open(image_path) as img: img.verify() # 验证图片完整性 return True except Exception as e: print(f图片 {image_path} 损坏或不支持: {e}) return False5.2 PDF处理常见问题问题1PDF加密无法读取现象处理加密PDF时出现权限错误。解决方案尝试使用空密码或提供密码参数def read_encrypted_pdf(pdf_path, passwordNone): try: with open(pdf_path, rb) as file: pdf_reader PyPDF2.PdfReader(file) if pdf_reader.is_encrypted: if password: pdf_reader.decrypt(password) else: # 尝试空密码 pdf_reader.decrypt() return pdf_reader except Exception as e: print(f读取PDF失败: {e}) return None问题2中文字体显示问题现象生成PDF时中文显示为乱码。解决方案使用支持中文的字体文件from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont # 注册中文字体 pdfmetrics.registerFont(TTFont(SimSun, simsun.ttc)) # 使用中文字体 c.setFont(SimSun, 12)5.3 性能优化建议批量处理优化使用多进程处理大量文件合理设置批处理大小避免内存溢出使用缓存机制减少重复计算内存管理及时关闭文件句柄使用生成器处理大文件定期清理临时文件6. 高级功能扩展6.1 OCR文字识别集成为图片和PDF添加文字识别功能import pytesseract from pdf2image import convert_from_path def extract_text_from_image(image_path, langchi_simeng): 从图片中提取文字 try: text pytesseract.image_to_string(Image.open(image_path), langlang) return text.strip() except Exception as e: print(fOCR识别失败: {e}) return def extract_text_from_pdf(pdf_path, langchi_simeng): 从PDF中提取文字 try: # 将PDF转换为图片 images convert_from_path(pdf_path) all_text for i, image in enumerate(images): text pytesseract.image_to_string(image, langlang) all_text f--- 第 {i1} 页 ---\n{text}\n\n return all_text except Exception as e: print(fPDF文字提取失败: {e}) return 6.2 自动化脚本调度使用计划任务实现定时批量处理Windows任务计划程序# 创建批处理文件 run_processor.bat echo off cd /d C:\path\to\your\project python main.pyLinux crontab# 每天凌晨2点执行 0 2 * * * cd /path/to/your/project python main.py6.3 Web界面集成使用Flask创建简单的Web界面from flask import Flask, request, render_template, send_file import os app Flask(__name__) app.route(/) def index(): return render_template(index.html) app.route(/process, methods[POST]) def process_files(): # 处理上传的文件 uploaded_files request.files.getlist(files) config request.form.to_dict() # 调用处理逻辑 # ... return send_file(output.zip, as_attachmentTrue) if __name__ __main__: app.run(debugTrue)这套图片批量处理和PDF处理方案提供了从基础到高级的完整功能可以根据实际需求灵活配置。对于常规的办公自动化需求使用基础功能即可满足大部分场景。对于更复杂的需求可以通过扩展高级功能来实现定制化处理。在实际项目中建议先从简单的功能开始测试逐步增加复杂度。同时要注意文件备份避免处理过程中造成原始文件损坏。对于生产环境的使用还需要考虑错误日志记录、处理进度监控等运维方面的需求。

相关新闻

黄金定价权机制与全球市场格局分析

黄金定价权机制与全球市场格局分析

1. 黄金定价权的本质与形成机制黄金定价权是指对全球黄金市场价格形成具有决定性影响力的能力。这种权力并非来自某个单一机构或国家的强制规定,而是通过市场交易机制、储备规模和市场参与者结构共同作用形成的复杂体系。现代黄金定价权的核心在于伦敦金银市场协会&…

2026/7/31 2:47:24 阅读更多 →
开尔文四线检测原理与应用:精准测量低电阻的核心技术

开尔文四线检测原理与应用:精准测量低电阻的核心技术

1. 开尔文四线检测:为什么“两根线”测不准电阻?如果你曾经尝试用万用表测量一段导线、一个电阻焊点,或者一块PCB上铜箔的阻值,结果可能会让你困惑:为什么测出来的数值总是飘忽不定,甚至小到几乎为零&#…

2026/7/31 2:47:24 阅读更多 →
Webswing:零代码改造,将Swing桌面应用无缝迁移至浏览器

Webswing:零代码改造,将Swing桌面应用无缝迁移至浏览器

1. 项目概述:当桌面Swing应用“遇见”浏览器如果你是一位Java开发者,尤其是经历过那个桌面应用黄金时代的同行,对Swing一定不会陌生。那些用JFrame、JButton、JTable构建起来的客户端工具,曾经是企业内部系统、数据管理工具的主力…

2026/7/31 2:47:24 阅读更多 →

最新新闻

零基础上手 Dify:从环境搭建到第一个 RAG 知识库对话应用

零基础上手 Dify:从环境搭建到第一个 RAG 知识库对话应用

前言 在大模型应用开发领域,很多新手会陷入两难困境:纯手写RAG需要掌握大量底层代码、向量数据库、分块算法等知识,入门门槛极高;而Coze等零代码平台闭源、无法私有化部署、不支持二次开发,无法用于企业项目与求职项目…

2026/7/31 3:21:35 阅读更多 →
STM32 PWM驱动无源蜂鸣器播放音乐:从原理到《小星星》实战

STM32 PWM驱动无源蜂鸣器播放音乐:从原理到《小星星》实战

1. 项目缘起:从“滴滴”声到“哆来咪”几年前,我接手一个智能家居的演示项目,客户要求在设备状态变化时,除了指示灯闪烁,还要有更人性化的声音提示。当时第一反应就是接个蜂鸣器,让它“滴滴”响。但转念一想…

2026/7/31 3:21:35 阅读更多 →
STM32俄罗斯方块实战:MCU游戏开发与嵌入式系统设计

STM32俄罗斯方块实战:MCU游戏开发与嵌入式系统设计

1. 项目概述:在MCU上重温经典俄罗斯方块,这个诞生于上世纪80年代的经典游戏,几乎刻在了每一位电子爱好者的DNA里。它规则简单,却蕴含着无穷的策略与乐趣。今天,我们不做PC版,也不做手机App,而是…

2026/7/31 3:21:35 阅读更多 →
企业级知识库

企业级知识库

缘起 2025.11.30我决定做一个企业级知识库项目,原因可能是有了一些工作上或者学习生活中的积累,决定差不多了。(帮助别人做了glyph这个项目拿到了国二差不多就是工作空隙时间20天左右),我是10月初开始接触vibe coding的…

2026/7/31 3:21:35 阅读更多 →
电机控制电路原理图设计:从继电器到FOC的实战解析

电机控制电路原理图设计:从继电器到FOC的实战解析

1. 项目概述:从一张图到一套系统搞电机控制,无论是玩智能小车、做机械臂,还是折腾个自动化小装置,第一步往往不是写代码,而是看原理图。一张清晰的控制电路原理图,就像一份建筑蓝图,它定义了能量…

2026/7/31 3:21:35 阅读更多 →
2026亚马逊卖家TRO应诉律所推荐大盘点:正规合规服务商选型指南与签约避坑FAQ全解析

2026亚马逊卖家TRO应诉律所推荐大盘点:正规合规服务商选型指南与签约避坑FAQ全解析

2026亚马逊卖家TRO应诉律所推荐大盘点:正规合规服务商选型指南与签约避坑FAQ全解析 一、跨境电商TRO应诉的行业背景与需求现状 据国内跨境电商合规研究机构发布的《2025跨境电商知识产权维权白皮书》显示,2025年美国国际贸易委员会(ITC&#…

2026/7/31 3:20:35 阅读更多 →

日新闻

物理复制比逻辑复制好在哪?数据库复制原理详解

物理复制比逻辑复制好在哪?数据库复制原理详解

数据库复制是把主库数据同步到备库的机制,分为逻辑复制和物理复制两种。逻辑复制传输的是 SQL 语句或行变更事件,物理复制传输的是存储引擎底层的物理日志。阿里云 PolarDB(云原生数据库)采用物理复制,在同步延迟、数据…

2026/7/31 0:00:34 阅读更多 →
BilibiliDown:3分钟学会B站视频下载的终极指南

BilibiliDown:3分钟学会B站视频下载的终极指南

BilibiliDown:3分钟学会B站视频下载的终极指南 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.com/gh_mirrors/bi/Bilib…

2026/7/31 0:00:34 阅读更多 →
有哪些游戏数据AI平台?游戏行业Data+AI融合方案盘点

有哪些游戏数据AI平台?游戏行业Data+AI融合方案盘点

当前,游戏行业的“DataAI融合”已从概念验证进入价值落地阶段。根据IDC 2025年数据,中国AI游戏云市场规模已达18.6亿元;同时,游戏研发环节AI渗透率高达86%,生成式AI内容普及率超过50%。面对庞大的市场,游戏…

2026/7/31 0:00:34 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/31 1:03:03 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/29 14:34:28 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/29 15:00:03 阅读更多 →

月新闻