调整Mediabox裁剪PDF下半部分失效,部分PDF无效果求助
问题:PDF处理脚本在部分文档上失效的原因分析
我编写了一个脚本,旨在将PDF文档的下半部分置为白色(文档尺寸保持不变,用于去除DHL、Hermes等德国快递公司面单的“说明”区域)。实现逻辑是:获取PDF页面,调整其Mediabox,再将该页面合并到一个尺寸相同的空白新页面中。
该脚本在目标PDF上可正常工作,但测试其他PDF时无效果,会完整复制原PDF内容(比如处理Veeam的产品概述文档时就出现此问题)。
相关代码如下:
import pypdf # PyPDF2, 3 and 4 are deprecated. PyPDF is currently in active development reader = pypdf.PdfReader(source_filename) writer = pypdf.PdfWriter() # get first page page = reader.pages[0] # create new page new_page = pypdf.PageObject.create_blank_page( None, width = page.mediabox.width, height = page.mediabox.height ) # crop original page.mediabox.bottom = ( page.mediabox.top - page.mediabox.bottom ) / 2 + page.mediabox.bottom # merge original into empty new page new_page.merge_page( page ) writer.add_page(new_page) with open(output_file, "wb") as fp: writer.write(fp)
失效原因分析
问题出在仅修改Mediabox不足以裁剪部分PDF的内容,因为PDF页面可能还包含其他优先级更高的边界框:
- 快递面单类PDF通常仅依赖Mediabox定义可见区域,所以修改Mediabox后合并,只会显示上半部分内容。
- 像Veeam这类规范的商业PDF,一般会同时设置
CropBox(专门定义页面实际显示/打印的区域)。当你只改Mediabox而不动CropBox时,merge_page会依据CropBox的范围渲染原页面,导致下半部分依然显示。 - 部分PDF的内容直接写在页面的Content Stream中,不受Mediabox限制,即使修改边界框,内容也会完整绘制。
修复方案
方案1:同步修改所有相关边界框
同时调整Mediabox、CropBox等所有影响内容显示的边界框:
import pypdf reader = pypdf.PdfReader(source_filename) writer = pypdf.PdfWriter() page = reader.pages[0] half_height = (page.mediabox.top - page.mediabox.bottom) / 2 new_bottom = page.mediabox.bottom + half_height # 遍历并修改所有相关边界框 for box_name in ['mediabox', 'cropbox', 'trimbox', 'artbox']: if hasattr(page, box_name): current_box = getattr(page, box_name) setattr(page, box_name, ( current_box.left, new_bottom, current_box.right, current_box.top )) new_page = pypdf.PageObject.create_blank_page(None, width=page.mediabox.width, height=page.mediabox.height) new_page.merge_page(page) writer.add_page(new_page) with open(output_file, "wb") as fp: writer.write(fp)
方案2:使用官方裁剪方法(更可靠)
利用pypdf自带的crop方法,它会同时处理边界框和内容流:
import pypdf reader = pypdf.PdfReader(source_filename) writer = pypdf.PdfWriter() page = reader.pages[0] # 定义裁剪区域:(left, bottom, right, top) cropped_page = page.crop(( page.mediabox.left, page.mediabox.bottom + (page.mediabox.top - page.mediabox.bottom)/2, page.mediabox.right, page.mediabox.top )) new_page = pypdf.PageObject.create_blank_page(None, width=page.mediabox.width, height=page.mediabox.height) new_page.merge_page(cropped_page) writer.add_page(new_page) with open(output_file, "wb") as fp: writer.write(fp)
内容的提问来源于stack exchange,提问作者Florian Kusche
相关产品推荐
相关产品推荐

