vis_utils.py 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. from magic_pdf.libs.commons import fitz
  2. import os
  3. def draw_bbox_on_page(raw_pdf_doc: fitz.Document, paras_dict:dict, save_path: str):
  4. """
  5. 在page上画出bbox,保存到save_path
  6. """
  7. # 检查文件是否存在
  8. is_new_pdf = False
  9. if os.path.exists(save_path):
  10. # 打开现有的 PDF 文件
  11. doc = fitz.open(save_path)
  12. else:
  13. # 创建一个新的空白 PDF 文件
  14. is_new_pdf = True
  15. doc = fitz.open('')
  16. color_map = {
  17. 'image': fitz.pdfcolor["yellow"],
  18. 'text': fitz.pdfcolor['blue'],
  19. "table": fitz.pdfcolor['green']
  20. }
  21. for k, v in paras_dict.items():
  22. page_idx = v['page_idx']
  23. width = raw_pdf_doc[page_idx].rect.width
  24. height = raw_pdf_doc[page_idx].rect.height
  25. new_page = doc.new_page(width=width, height=height)
  26. shape = new_page.new_shape()
  27. for order, block in enumerate(v['preproc_blocks']):
  28. rect = fitz.Rect(block['bbox'])
  29. shape = new_page.new_shape()
  30. shape.draw_rect(rect)
  31. shape.finish(color=None, fill=color_map['text'], fill_opacity=0.2)
  32. shape.finish()
  33. shape.commit()
  34. for img in v['images']:
  35. # 原始box画上去
  36. rect = fitz.Rect(img['bbox'])
  37. shape = new_page.new_shape()
  38. shape.draw_rect(rect)
  39. shape.finish(color=None, fill=fitz.pdfcolor['yellow'])
  40. shape.finish()
  41. shape.commit()
  42. for img in v['image_backup']:
  43. # 原始box画上去
  44. rect = fitz.Rect(img['bbox'])
  45. shape = new_page.new_shape()
  46. shape.draw_rect(rect)
  47. shape.finish(color=fitz.pdfcolor['yellow'], fill=None)
  48. shape.finish()
  49. shape.commit()
  50. for tb in v['droped_text_block']:
  51. # 原始box画上去
  52. rect = fitz.Rect(tb['bbox'])
  53. shape = new_page.new_shape()
  54. shape.draw_rect(rect)
  55. shape.finish(color=None, fill=fitz.pdfcolor['black'], fill_opacity=0.4)
  56. shape.finish()
  57. shape.commit()
  58. # TODO table
  59. for tb in v['tables']:
  60. rect = fitz.Rect(tb['bbox'])
  61. shape = new_page.new_shape()
  62. shape.draw_rect(rect)
  63. shape.finish(color=None, fill=fitz.pdfcolor['green'], fill_opacity=0.2)
  64. shape.finish()
  65. shape.commit()
  66. parent_dir = os.path.dirname(save_path)
  67. if not os.path.exists(parent_dir):
  68. os.makedirs(parent_dir)
  69. if is_new_pdf:
  70. doc.save(save_path)
  71. else:
  72. doc.saveIncr()
  73. doc.close()
  74. def debug_show_bbox(raw_pdf_doc: fitz.Document, page_idx: int, bboxes: list, droped_bboxes:list, expect_drop_bboxes:list, save_path: str, expected_page_id:int):
  75. """
  76. 以覆盖的方式写个临时的pdf,用于debug
  77. """
  78. if page_idx!=expected_page_id:
  79. return
  80. if os.path.exists(save_path):
  81. # 删除已经存在的文件
  82. os.remove(save_path)
  83. # 创建一个新的空白 PDF 文件
  84. doc = fitz.open('')
  85. width = raw_pdf_doc[page_idx].rect.width
  86. height = raw_pdf_doc[page_idx].rect.height
  87. new_page = doc.new_page(width=width, height=height)
  88. shape = new_page.new_shape()
  89. for bbox in bboxes:
  90. # 原始box画上去
  91. rect = fitz.Rect(*bbox[0:4])
  92. shape = new_page.new_shape()
  93. shape.draw_rect(rect)
  94. shape.finish(color=fitz.pdfcolor['red'], fill=fitz.pdfcolor['blue'], fill_opacity=0.2)
  95. shape.finish()
  96. shape.commit()
  97. for bbox in droped_bboxes:
  98. # 原始box画上去
  99. rect = fitz.Rect(*bbox[0:4])
  100. shape = new_page.new_shape()
  101. shape.draw_rect(rect)
  102. shape.finish(color=None, fill=fitz.pdfcolor['yellow'], fill_opacity=0.2)
  103. shape.finish()
  104. shape.commit()
  105. for bbox in expect_drop_bboxes:
  106. # 原始box画上去
  107. rect = fitz.Rect(*bbox[0:4])
  108. shape = new_page.new_shape()
  109. shape.draw_rect(rect)
  110. shape.finish(color=fitz.pdfcolor['red'], fill=None)
  111. shape.finish()
  112. shape.commit()
  113. # shape.insert_textbox(fitz.Rect(200, 0, 600, 20), f"total bboxes: {len(bboxes)}", fontname="helv", fontsize=12,
  114. # color=(0, 0, 0))
  115. # shape.finish(color=fitz.pdfcolor['black'])
  116. # shape.commit()
  117. parent_dir = os.path.dirname(save_path)
  118. if not os.path.exists(parent_dir):
  119. os.makedirs(parent_dir)
  120. doc.save(save_path)
  121. doc.close()
  122. def debug_show_page(page, bboxes1: list,bboxes2: list,bboxes3: list,):
  123. save_path = "./tmp/debug.pdf"
  124. if os.path.exists(save_path):
  125. # 删除已经存在的文件
  126. os.remove(save_path)
  127. # 创建一个新的空白 PDF 文件
  128. doc = fitz.open('')
  129. width = page.rect.width
  130. height = page.rect.height
  131. new_page = doc.new_page(width=width, height=height)
  132. shape = new_page.new_shape()
  133. for bbox in bboxes1:
  134. # 原始box画上去
  135. rect = fitz.Rect(*bbox[0:4])
  136. shape = new_page.new_shape()
  137. shape.draw_rect(rect)
  138. shape.finish(color=fitz.pdfcolor['red'], fill=fitz.pdfcolor['blue'], fill_opacity=0.2)
  139. shape.finish()
  140. shape.commit()
  141. for bbox in bboxes2:
  142. # 原始box画上去
  143. rect = fitz.Rect(*bbox[0:4])
  144. shape = new_page.new_shape()
  145. shape.draw_rect(rect)
  146. shape.finish(color=None, fill=fitz.pdfcolor['yellow'], fill_opacity=0.2)
  147. shape.finish()
  148. shape.commit()
  149. for bbox in bboxes3:
  150. # 原始box画上去
  151. rect = fitz.Rect(*bbox[0:4])
  152. shape = new_page.new_shape()
  153. shape.draw_rect(rect)
  154. shape.finish(color=fitz.pdfcolor['red'], fill=None)
  155. shape.finish()
  156. shape.commit()
  157. parent_dir = os.path.dirname(save_path)
  158. if not os.path.exists(parent_dir):
  159. os.makedirs(parent_dir)
  160. doc.save(save_path)
  161. doc.close()
  162. def draw_layout_bbox_on_page(raw_pdf_doc: fitz.Document, paras_dict:dict, header, footer, pdf_path: str):
  163. """
  164. 在page上画出bbox,保存到save_path
  165. """
  166. # 检查文件是否存在
  167. is_new_pdf = False
  168. if os.path.exists(pdf_path):
  169. # 打开现有的 PDF 文件
  170. doc = fitz.open(pdf_path)
  171. else:
  172. # 创建一个新的空白 PDF 文件
  173. is_new_pdf = True
  174. doc = fitz.open('')
  175. for k, v in paras_dict.items():
  176. page_idx = v['page_idx']
  177. layouts = v['layout_bboxes']
  178. page = doc[page_idx]
  179. shape = page.new_shape()
  180. for order, layout in enumerate(layouts):
  181. border_offset = 1
  182. rect_box = layout['layout_bbox']
  183. layout_label = layout['layout_label']
  184. fill_color = fitz.pdfcolor['pink'] if layout_label=='U' else None
  185. rect_box = [rect_box[0]+1, rect_box[1]-border_offset, rect_box[2]-1, rect_box[3]+border_offset]
  186. rect = fitz.Rect(*rect_box)
  187. shape.draw_rect(rect)
  188. shape.finish(color=fitz.pdfcolor['red'], fill=fill_color, fill_opacity=0.4)
  189. """
  190. draw order text on layout box
  191. """
  192. font_size = 10
  193. shape.insert_text((rect_box[0] + 1, rect_box[1] + font_size), f"{order}", fontsize=font_size, color=(0, 0, 0))
  194. """画上footer header"""
  195. if header:
  196. shape.draw_rect(fitz.Rect(header))
  197. shape.finish(color=None, fill=fitz.pdfcolor['black'], fill_opacity=0.2)
  198. if footer:
  199. shape.draw_rect(fitz.Rect(footer))
  200. shape.finish(color=None, fill=fitz.pdfcolor['black'], fill_opacity=0.2)
  201. shape.commit()
  202. if is_new_pdf:
  203. doc.save(pdf_path)
  204. else:
  205. doc.saveIncr()
  206. doc.close()
  207. @DeprecationWarning
  208. def draw_layout_on_page(raw_pdf_doc: fitz.Document, page_idx: int, page_layout: list, pdf_path: str):
  209. """
  210. 把layout的box用红色边框花在pdf_path的page_idx上
  211. """
  212. def draw(shape, layout, fill_color=fitz.pdfcolor['pink']):
  213. border_offset = 1
  214. rect_box = layout['layout_bbox']
  215. layout_label = layout['layout_label']
  216. sub_layout = layout['sub_layout']
  217. if len(sub_layout)==0:
  218. fill_color = fill_color if layout_label=='U' else None
  219. rect_box = [rect_box[0]+1, rect_box[1]-border_offset, rect_box[2]-1, rect_box[3]+border_offset]
  220. rect = fitz.Rect(*rect_box)
  221. shape.draw_rect(rect)
  222. shape.finish(color=fitz.pdfcolor['red'], fill=fill_color, fill_opacity=0.2)
  223. # if layout_label=='U':
  224. # bad_boxes = layout.get("bad_boxes", [])
  225. # for bad_box in bad_boxes:
  226. # rect = fitz.Rect(*bad_box)
  227. # shape.draw_rect(rect)
  228. # shape.finish(color=fitz.pdfcolor['red'], fill=fitz.pdfcolor['red'], fill_opacity=0.2)
  229. # else:
  230. # rect = fitz.Rect(*rect_box)
  231. # shape.draw_rect(rect)
  232. # shape.finish(color=fitz.pdfcolor['blue'])
  233. for sub_layout in sub_layout:
  234. draw(shape, sub_layout)
  235. shape.commit()
  236. # 检查文件是否存在
  237. is_new_pdf = False
  238. if os.path.exists(pdf_path):
  239. # 打开现有的 PDF 文件
  240. doc = fitz.open(pdf_path)
  241. else:
  242. # 创建一个新的空白 PDF 文件
  243. is_new_pdf = True
  244. doc = fitz.open('')
  245. page = doc[page_idx]
  246. shape = page.new_shape()
  247. for order, layout in enumerate(page_layout):
  248. draw(shape, layout, fitz.pdfcolor['yellow'])
  249. # shape.insert_textbox(fitz.Rect(200, 0, 600, 20), f"total bboxes: {len(layout)}", fontname="helv", fontsize=12,
  250. # color=(0, 0, 0))
  251. # shape.finish(color=fitz.pdfcolor['black'])
  252. # shape.commit()
  253. parent_dir = os.path.dirname(pdf_path)
  254. if not os.path.exists(parent_dir):
  255. os.makedirs(parent_dir)
  256. if is_new_pdf:
  257. doc.save(pdf_path)
  258. else:
  259. doc.saveIncr()
  260. doc.close()