如何限制pdfminer仅读取cropbox或mediabox范围内的数据
pdfminer限制仅读取CropBox/MediaBox范围内容的配置方法
pdfminer(当前维护版本为pdfminer.six)本身内置了页框裁剪支持,不需要手动做复杂的后处理,按下面的方式配置即可:
1. 原生参数配置(推荐,性能最优)
PDFPage.get_pages()方法提供了原生的裁剪控制参数,解析阶段就会直接过滤范围外的内容,不会生成多余的布局对象,性能远高于事后遍历过滤:
- 若要仅读取CropBox范围内的内容:保持默认参数即可,也可以显式传入
cropbox=True明确规则,这也是pdfminer的默认行为,会自动忽略CropBox裁剪区域外的所有内容 - 若要强制读取完整MediaBox范围的内容、忽略PDF自带的CropBox裁剪设置:调用
get_pages()时传入cropbox=False即可
对应修改原示例代码的页面读取行即可:
# 仅读取CropBox范围内容(默认配置,显式传参可读性更高) pages = PDFPage.get_pages(fp, cropbox=True) # 切换为仅读取完整MediaBox范围内容 # pages = PDFPage.get_pages(fp, cropbox=False)
注意:如果你使用的是停止维护的旧版原版pdfminer(非pdfminer.six),可能存在CropBox裁剪失效的bug,升级到最新版pdfminer.six即可修复。
2. 自定义范围过滤(适配灵活裁剪需求)
如果需要自定义裁剪范围,或者需要自己控制过滤逻辑(比如保留和范围部分重叠的内容),可以在遍历布局对象时手动做bbox坐标判断:
- 每个
page对象自带cropbox、mediabox属性,直接存储了对应页框的坐标,格式为(x0, y0, x1, y1),和布局对象的bbox属性格式完全一致 - 拿到目标范围坐标后,判断布局对象的bbox和目标范围的位置关系,过滤不符合要求的对象即可
对应修改后的完整示例代码如下:
from pdfminer.layout import LAParams, LTTextBox from pdfminer.pdfpage import PDFPage from pdfminer.pdfinterp import PDFResourceManager from pdfminer.pdfinterp import PDFPageInterpreter from pdfminer.converter import PDFPageAggregator fp = open("my_pdf", 'rb') rsrcmgr, laparams = PDFResourceManager(), LAParams() device = PDFPageAggregator(rsrcmgr, laparams=laparams) interpreter = PDFPageInterpreter(rsrcmgr, device) pages = PDFPage.get_pages(fp, cropbox=True) for page in pages: # 读取目标范围,替换为page.mediabox即可使用MediaBox做过滤基准 target_x0, target_y0, target_x1, target_y1 = page.cropbox interpreter.process_page(page) layout = device.get_result() for lobj in layout: if isinstance(lobj, LTTextBox): x0, y0, x1, y1 = lobj.bbox # 仅保留完全落在目标范围内的文本框,若需要保留部分重叠的内容可调整判断条件 if not (x0 >= target_x0 and y0 >= target_y0 and x1 <= target_x1 and y1 <= target_y1): continue x, y, text = lobj.bbox[0], lobj.bbox[3], lobj.get_text() print('At %r is text: %s' % ((x, y), repr(text)))
内容的提问来源于stack exchange,提问作者Vricken
相关产品推荐
相关产品推荐

