Python脚本高亮PDF后文件体积过大,如何优化?
优化大PDF高亮标注的Python-fitz方案
针对700页PDF处理时体积过大、脚本崩溃的问题,可从内存管控、压缩优化、逻辑精简三个方向进行优化:
1. 分批处理+增量保存,降低内存负载
一次性加载全量页面会占用大量内存,导致程序崩溃。通过分批处理页面,每完成一批就增量保存并释放内存,可有效缓解内存压力。
2. 启用PDF压缩与垃圾回收,减小输出体积
利用fitz的保存参数启用压缩,并清理PDF中的无用对象,能大幅降低输出文件的体积。
3. 精准定位页面,减少冗余搜索
如果从Kindle MyClippings.txt提取标注时能拿到对应页码,直接定位到目标页面搜索文本,避免遍历所有页面,提升处理效率。
通用优化代码(无页码映射)
import fitz def highlight_pdf(input_path, output_path, text_list, batch_size=50): doc = fitz.open(input_path) total_pages = len(doc) for start in range(0, total_pages, batch_size): end = min(start + batch_size, total_pages) # 处理当前批次页面 for page_num in range(start, end): page = doc[page_num] for text in text_list: quads = page.search_for(text, quads=True) if quads: page.add_highlight_annot(quads) # 清理页面冗余内容,释放内存 page.clean_contents() # 增量保存,仅写入修改部分 doc.save(output_path, incremental=True, garbage=3, compression=fitz.PDF_COMPRESSION_DEFLATE) # 重置文档状态,释放已处理页面内存 doc.reload() # 最终完整保存并关闭文档 doc.save(output_path, garbage=3, compression=fitz.PDF_COMPRESSION_DEFLATE) doc.close() # 使用示例 text_list = [ "first piece of text", "second piece of text", "third piece of text" ] highlight_pdf("text_to_highlight.pdf", "text_annotated.pdf", text_list)
关键参数说明:
batch_size=50:每批处理50页,可根据自身内存情况调整incremental=True:增量保存模式,大幅提升保存速度并减少内存占用garbage=3:彻底清理PDF中未使用的资源、旧版本内容等无用对象compression=fitz.PDF_COMPRESSION_DEFLATE:启用Deflate压缩,显著减小输出文件体积page.clean_contents():清理页面的冗余内容,释放单页占用的内存
进阶优化代码(带页码映射)
如果从MyClippings.txt提取的标注包含对应页码,可直接定位页面处理,避免全量遍历:
import fitz # 假设从MyClippings.txt提取的标注格式:{原书页码: [标注文本列表]} annotations_by_page = { 10: ["first piece of text"], 25: ["second piece of text"], # ... 其他页码与对应文本 } def highlight_pdf_with_pages(input_path, output_path, annotations_by_page): doc = fitz.open(input_path) for book_page, text_list in annotations_by_page.items(): # fitz的页码从0开始,需将原书页码减1 page = doc[book_page - 1] for text in text_list: quads = page.search_for(text, quads=True) if quads: page.add_highlight_annot(quads) page.clean_contents() doc.save(output_path, garbage=3, compression=fitz.PDF_COMPRESSION_DEFLATE) doc.close() # 使用示例 highlight_pdf_with_pages("text_to_highlight.pdf", "text_annotated.pdf", annotations_by_page)
内容的提问来源于stack exchange,提问作者Ramiro
相关产品推荐
相关产品推荐

