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轉圖像功能,特別適合需要高質量轉換的學術、出版和設計工作場景。