Python 脚本,用于将 PDF 文件高质量地转换为 PNG 图像
import os
import fitz # PyMuPDF
from PIL import Image
import argparse
import logging
from tqdm import tqdm# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger('PDF2PNG')def convert_pdf_to_png(pdf_path, output_dir, dpi=300, zoom_factor=4.0, image_format='PNG', grayscale=False, crop_to_content=False, quality=95):"""将PDF文件转换为高质量的PNG图像参数:pdf_path (str): PDF文件路径output_dir (str): 输出目录dpi (int): 输出图像DPI (默认300)zoom_factor (float): 缩放因子,提高图像质量 (默认4.0)image_format (str): 输出格式 ('PNG', 'JPEG', 'TIFF')grayscale (bool): 是否转换为灰度图像crop_to_content (bool): 是否裁剪到内容区域quality (int): 输出质量 (1-100)"""try:# 验证输入路径if not os.path.isfile(pdf_path):raise FileNotFoundError(f"PDF文件不存在: {pdf_path}")# 创建输出目录os.makedirs(output_dir, exist_ok=True)# 打开PDF文件pdf_document = fitz.open(pdf_path)total_pages = len(pdf_document)logger.info(f"开始转换: {os.path.basename(pdf_path)}")logger.info(f"总页数: {total_pages}")logger.info(f"输出DPI: {dpi}, 缩放因子: {zoom_factor}, 格式: {image_format}")# 创建进度条pbar = tqdm(total=total_pages, desc="转换进度", unit="页")for page_num in range(total_pages):page = pdf_document.load_page(page_num)# 计算缩放矩阵zoom_matrix = fitz.Matrix(zoom_factor, zoom_factor)# 获取页面内容边界(用于裁剪)if crop_to_content:content_rect = page.get_textpage().boundrectif not content_rect.is_empty:clip_rect = content_rect * zoom_matrixelse:clip_rect = page.rect * zoom_matrixelse:clip_rect = page.rect * zoom_matrix# 渲染页面为像素图pix = page.get_pixmap(matrix=zoom_matrix, clip=clip_rect, alpha=False)# 转换为PIL图像img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)# 转换为灰度if grayscale:img = img.convert("L")# 生成输出文件名base_name = os.path.splitext(os.path.basename(pdf_path))[0]output_path = os.path.join(output_dir, f"{base_name}_page_{page_num+1:03d}.{image_format.lower()}")# 保存图像if image_format == 'PNG':img.save(output_path, format='PNG', compress_level=2)elif image_format == 'JPEG':img.save(output_path, format='JPEG', quality=quality, subsampling=0)elif image_format == 'TIFF':img.save(output_path, format='TIFF', compression='tiff_lzw')else:raise ValueError(f"不支持的图像格式: {image_format}")pbar.update(1)pbar.close()pdf_document.close()logger.info(f"转换完成! 输出目录: {output_dir}")except Exception as e:logger.error(f"转换过程中出错: {str(e)}")raisedef main():parser = argparse.ArgumentParser(description='将PDF文件转换为高质量PNG图像')parser.add_argument('input_pdf', type=str, help='输入PDF文件路径')parser.add_argument('output_dir', type=str, help='输出目录路径')parser.add_argument('--dpi', type=int, default=300, help='输出图像DPI (默认300)')parser.add_argument('--zoom', type=float, default=4.0, help='缩放因子 (默认4.0)')parser.add_argument('--format', type=str, default='PNG', choices=['PNG', 'JPEG', 'TIFF'], help='输出图像格式 (默认PNG)')parser.add_argument('--grayscale', action='store_true', help='转换为灰度图像')parser.add_argument('--crop', action='store_true', help='裁剪到内容区域')parser.add_argument('--quality', type=int, default=95, choices=range(1, 101), metavar="[1-100]", help='输出质量 (默认95)')args = parser.parse_args()try:convert_pdf_to_png(pdf_path=args.input_pdf,output_dir=args.output_dir,dpi=args.dpi,zoom_factor=args.zoom,image_format=args.format,grayscale=args.grayscale,crop_to_content=args.crop,quality=args.quality)except Exception as e:logger.error(f"转换失败: {str(e)}")exit(1)if __name__ == "__main__":main()
使用说明
安装依赖
pip install PyMuPDF Pillow tqdm
命令行使用
# 基本用法
python pdf_to_png.py input.pdf output_directory# 高级选项
python pdf_to_png.py input.pdf output_directory \--dpi 600 \ # 设置DPI为600--zoom 5.0 \ # 提高缩放因子--format JPEG \ # 输出为JPEG格式--grayscale \ # 转换为灰度图像--crop \ # 裁剪到内容区域--quality 90 # 设置JPEG质量为90
功能特点
-
高质量输出:
- 使用高DPI设置(默认300 DPI)
- 通过缩放因子提升渲染质量(默认4.0)
- 支持PNG、JPEG、TIFF三种输出格式
-
智能处理:
- 内容感知裁剪(
--crop
选项) - 灰度转换(
--grayscale
选项) - 进度条显示转换进度
- 内容感知裁剪(
-
健壮性:
- 完善的错误处理
- 输入文件验证
- 自动创建输出目录
-
性能优化:
- 批量处理多页文档
- 内存高效管理
- 支持大文件处理
技术说明
-
渲染质量:
- 使用
zoom_factor
参数控制渲染质量(值越高越清晰) - DPI 与缩放因子关系:实际DPI = zoom_factor × 72
- 使用
-
内容裁剪:
- 基于文本内容自动检测边界
- 移除不必要的空白区域
- 特别适合扫描文档处理
-
格式选项:
- PNG:无损压缩,适合文本和线条图
- JPEG:有损压缩,适合照片内容
- TIFF:高质量存档格式,支持多页
常见问题解决
-
中文路径问题:
# 在脚本开头添加 import sys sys.stdout.reconfigure(encoding='utf-8')
-
内存不足处理:
- 降低
zoom_factor
值 - 分批次处理大型PDF
- 降低
-
安装问题:
- Windows用户可能需要安装Microsoft Visual C++ Redistributable
- Linux用户确保安装libjpeg和zlib开发包
此脚本提供了专业级的PDF转图像功能,特别适合需要高质量转换的学术、出版和设计工作场景。