如何通过PyPDF结合高亮坐标与visitor_text提取注释文本?
如何用PyPDF结合高亮注释坐标提取对应文本?
核心思路
要关联高亮注释的QuadPoints坐标和visitor_text回调,需先将高亮区域转换为可判断的边界框,再在遍历文本时检查每个文本片段的坐标是否落在该边界框内。
完整实现代码
from pypdf import PdfReader def extract_highlighted_text(pdf_path): reader = PdfReader(pdf_path) highlighted_texts = [] for page_num, page in enumerate(reader.pages): # 收集当前页面所有高亮区域的边界框 highlight_bboxes = [] if "/Annots" in page: for annot in page["/Annots"]: annot_obj = annot.get_object() if annot_obj["/Subtype"] == "/Highlight": quad_points = annot_obj["/QuadPoints"] # 提取所有x、y坐标,计算高亮区域的最小/最大边界 xs = quad_points[0::2] ys = quad_points[1::2] x_min, x_max = min(xs), max(xs) y_min, y_max = min(ys), max(ys) highlight_bboxes.append((x_min, x_max, y_min, y_max)) # 遍历页面文本,筛选高亮区域内的内容 page_highlights = [] def visitor(text, cm, tm, font_dict, font_size): # tm矩阵提供文本位置:tm[4]是x起始坐标,tm[5]是文本基线y坐标 text_x = tm[4] text_y_base = tm[5] # 文本垂直覆盖范围:基线到顶部(近似为基线+字体大小) text_y_top = text_y_base + font_size # 检查当前文本是否落在任意高亮区域内 for (hl_x_min, hl_x_max, hl_y_min, hl_y_max) in highlight_bboxes: # 水平:文本起始x在高亮x区间;垂直:文本范围与高亮范围有重叠 if (hl_x_min <= text_x <= hl_x_max) and (text_y_base <= hl_y_max and text_y_top >= hl_y_min): page_highlights.append(text) break # 触发文本提取,执行visitor回调 page.extract_text(visitor_text=visitor) if page_highlights: highlighted_texts.append(f"第{page_num+1}页高亮文本: {' '.join(page_highlights)}") return highlighted_texts # 调用示例 if __name__ == "__main__": for segment in extract_highlighted_text("commented.pdf"): print(segment)
关键细节说明
高亮边界框计算
QuadPoints是高亮矩形的四个顶点坐标,格式为[x1,y1,x2,y2,x3,y3,x4,y4]。通过提取所有x坐标的最小/最大值、y坐标的最小/最大值,得到高亮区域的矩形边界框,方便后续范围判断。文本坐标对应
visitor_text回调中的tm(文本矩阵):tm[4]:当前文本片段的起始x坐标tm[5]:当前文本片段的基线y坐标(PDF坐标原点在页面左下角,y轴向上)
文本的垂直覆盖范围近似为[tm[5], tm[5]+font_size](基线到文本顶部)。
筛选逻辑
只要文本片段的起始x落在高亮区域的x区间内,且垂直范围与高亮区域有重叠,就判定为高亮文本。这个简化逻辑能覆盖大多数常规高亮场景;如果需要更精确的匹配,可以结合字体宽度计算文本结束x,但PyPDF未直接提供该参数,需额外处理。
内容的提问来源于stack exchange,提问作者TunaFFish
相关产品推荐
相关产品推荐

