如何用Python实现PDF转黑白、指定300DPI并按新名保存?
解决PDF转黑白、固定300DPI并重命名保存的需求
嘿,针对你的需求,reportlab 和 pdfrw 其实不太适合直接处理现有PDF的色彩转换和DPI调整——它们更偏向生成新PDF或者做简单的内容修改。我个人更推荐两个工具:PyMuPDF(也就是fitz) 和 Ghostscript,前者是纯Python库,易用性拉满;后者是专业的PDF处理工具,处理这类转换的效率和效果都很靠谱。
方案一:使用PyMuPDF(fitz)
PyMuPDF可以轻松打开现有PDF,处理页面色彩,还能精准控制输出DPI,完全覆盖你的需求。
步骤1:安装依赖
先把PyMuPDF装上:
pip install pymupdf
步骤2:示例代码
下面的代码会遍历指定文件夹里的所有PDF,将每个文件转为黑白,以300DPI保存,同时自动重命名(比如原文件名后加_bw_300dpi):
import fitz # 导入PyMuPDF库 import os def convert_pdf_to_bw_300dpi(input_folder, output_folder): # 确保输出文件夹存在,不存在就创建 os.makedirs(output_folder, exist_ok=True) # 遍历输入文件夹里的PDF文件 for filename in os.listdir(input_folder): if filename.lower().endswith('.pdf'): input_path = os.path.join(input_folder, filename) # 构造新的输出文件名 name, ext = os.path.splitext(filename) output_filename = f"{name}_bw_300dpi{ext}" output_path = os.path.join(output_folder, output_filename) # 打开目标PDF doc = fitz.open(input_path) # 逐个处理页面 for page in doc: # 将页面色彩空间转为灰度,实现黑白转换 page.set_colorspace(fitz.csGRAY) # 以300DPI生成页面像素图 pix = page.get_pixmap(dpi=300) # 用处理后的页面替换原页面 doc.insert_page(page.number, pixmap=pix) doc.delete_page(page.number + 1) # 删除未处理的原页面 # 保存处理后的PDF doc.save(output_path) doc.close() print(f"已完成处理:{output_path}") # 替换成你自己的文件夹路径 input_dir = "./your_input_pdfs" output_dir = "./processed_pdfs" convert_pdf_to_bw_300dpi(input_dir, output_dir)
代码细节说明
page.set_colorspace(fitz.csGRAY):强制把页面的色彩空间切换为灰度,直接去除所有色彩信息。page.get_pixmap(dpi=300):以300DPI的分辨率生成页面的像素图,保证输出PDF的DPI固定。- 通过插入新页面再删除原页面的方式,既保留了原PDF的结构,又替换了处理后的内容。
方案二:使用Ghostscript(推荐批量处理)
如果要处理大量PDF,Ghostscript的效率会更高,它是专门的PDF/PostScript处理工具,参数设置更灵活,对复杂PDF的兼容性也更好。
步骤1:安装Ghostscript
- Windows:从官网下载安装包,记得把安装路径添加到系统环境变量
PATH中。 - macOS:用Homebrew安装:
brew install ghostscript - Linux:用包管理器安装,比如
apt install ghostscript
步骤2:Python调用Ghostscript的示例代码
通过subprocess模块调用Ghostscript命令,实现批量转换:
import os import subprocess def convert_with_ghostscript(input_folder, output_folder): os.makedirs(output_folder, exist_ok=True) for filename in os.listdir(input_folder): if filename.lower().endswith('.pdf'): input_path = os.path.join(input_folder, filename) name, ext = os.path.splitext(filename) output_path = os.path.join(output_folder, f"{name}_bw_300dpi{ext}") # Ghostscript核心命令参数:转黑白、固定300DPI、保证输出质量 gs_command = [ "gs", "-sDEVICE=pdfwrite", "-dPDFSETTINGS=/prepress", # 高质量输出预设 "-dColorConversionStrategy=/Gray", # 强制转为灰度 "-dProcessColorModel=/DeviceGray", "-dDownsampleColorImages=false", "-dDownsampleGrayImages=false", "-dDownsampleMonoImages=false", # 禁止自动下采样,保留300DPI "-r300", # 设置输出DPI为300 "-o", output_path, # 指定输出路径 input_path # 输入PDF路径 ] # 执行转换命令 subprocess.run(gs_command, check=True) print(f"已完成处理:{output_path}") # 替换成你自己的文件夹路径 input_dir = "./your_input_pdfs" output_dir = "./processed_pdfs" convert_with_ghostscript(input_dir, output_dir)
参数说明
-dColorConversionStrategy=/Gray和-dProcessColorModel=/DeviceGray:彻底将所有色彩元素转为灰度。-r300:直接固定输出PDF的DPI为300。-dDownsample...=false:避免Ghostscript自动压缩图片,确保300DPI的分辨率不被降低。
选择建议
- 如果你需要纯Python运行环境,不想额外安装工具,选PyMuPDF就足够好用。
- 如果要处理大量PDF,或者需要更精细的输出控制(比如压缩选项),Ghostscript是更优选择。
内容的提问来源于stack exchange,提问作者blokeley




