Only do detailed page analysis when needed by --redo-ocr
This commit is contained in:
@@ -162,6 +162,10 @@ def repair_and_parse_pdf(
|
||||
options = context.get_options()
|
||||
copyfile(input_file, output_file)
|
||||
|
||||
detailed_page_analysis = False
|
||||
if options.redo_ocr:
|
||||
detailed_page_analysis = True
|
||||
|
||||
try:
|
||||
pdfinfo = PdfInfo(output_file, log=log)
|
||||
except pikepdf.PasswordError as e:
|
||||
|
||||
@@ -27,7 +27,7 @@ import re
|
||||
from pikepdf import PdfMatrix
|
||||
import pikepdf
|
||||
|
||||
from .ghosttext import extract_text_xml
|
||||
from . import ghosttext
|
||||
from .layout import get_page_analysis, get_text_boxes
|
||||
|
||||
from ..helpers import fspath
|
||||
@@ -564,18 +564,20 @@ def _pdf_get_pageinfo(pdf, pageno: int, infile, xmltext):
|
||||
pageinfo['images'] = []
|
||||
|
||||
page = pdf.pages[pageno]
|
||||
|
||||
# pageinfo['textinfo'] = _page_get_textblocks(
|
||||
# fspath(infile), pageno, xmltext=xmltext)
|
||||
pscript5_mode = str(pdf.metadata.get('/Creator')).startswith('PScript5')
|
||||
miner = get_page_analysis(infile, pageno, pscript5_mode)
|
||||
pageinfo['textboxes'] = list(simplify_textboxes(miner))
|
||||
|
||||
mediabox = [Decimal(d) for d in page.MediaBox.as_list()]
|
||||
width_pt = mediabox[2] - mediabox[0]
|
||||
height_pt = mediabox[3] - mediabox[1]
|
||||
|
||||
bboxes = (box.bbox for box in pageinfo['textboxes'])
|
||||
if xmltext:
|
||||
bboxes = ghosttext.page_get_textblocks(
|
||||
fspath(infile), pageno, xmltext=xmltext, height=height_pt)
|
||||
pageinfo['bboxes'] = bboxes
|
||||
else:
|
||||
pscript5_mode = str(pdf.metadata.get('/Creator')).startswith('PScript5')
|
||||
miner = get_page_analysis(infile, pageno, pscript5_mode)
|
||||
pageinfo['textboxes'] = list(simplify_textboxes(miner))
|
||||
bboxes = (box.bbox for box in pageinfo['textboxes'])
|
||||
|
||||
pageinfo['has_text'] = _page_has_text(
|
||||
bboxes, width_pt, height_pt
|
||||
)
|
||||
@@ -615,16 +617,20 @@ def _pdf_get_pageinfo(pdf, pageno: int, infile, xmltext):
|
||||
return pageinfo
|
||||
|
||||
|
||||
def _pdf_get_all_pageinfo(infile, log=None):
|
||||
def _pdf_get_all_pageinfo(infile, detailed_page_analysis, log=None):
|
||||
if not log:
|
||||
log = Mock()
|
||||
|
||||
pdf = pikepdf.open(infile)
|
||||
page_xml = extract_text_xml(infile, pdf, pageno=None, log=log)
|
||||
if not detailed_page_analysis:
|
||||
pages_xml = None
|
||||
else:
|
||||
pages_xml = ghosttext.extract_text_xml(infile, pdf, pageno=None, log=log)
|
||||
|
||||
pages = []
|
||||
for n in range(len(pdf.pages)):
|
||||
page = PageInfo(pdf, n, infile, page_xml[n])
|
||||
page_xml = pages_xml[n] if pages_xml else None
|
||||
page = PageInfo(pdf, n, infile, page_xml)
|
||||
pages.append(page)
|
||||
|
||||
return pages, pdf
|
||||
@@ -694,9 +700,16 @@ class PageInfo:
|
||||
result = False
|
||||
return result
|
||||
|
||||
if 'textboxes' not in self._pageinfo:
|
||||
if visible is not None and corrupt is not None:
|
||||
raise NotImplementedError(
|
||||
'Ghostscript textboxes cannot be classified')
|
||||
return self._pageinfo['bboxes']
|
||||
|
||||
return (obj.bbox for obj in self._pageinfo['textboxes']
|
||||
if predicate(obj, visible, corrupt))
|
||||
|
||||
|
||||
@property
|
||||
def xres(self):
|
||||
return self._pageinfo.get('xres', None)
|
||||
@@ -729,9 +742,10 @@ class PageInfo:
|
||||
class PdfInfo:
|
||||
"""Get summary information about a PDF"""
|
||||
|
||||
def __init__(self, infile, log=None):
|
||||
def __init__(self, infile, detailed_page_analysis=False, log=None):
|
||||
self._infile = infile
|
||||
self._pages, pdf = _pdf_get_all_pageinfo(infile, log=log)
|
||||
self._pages, pdf = _pdf_get_all_pageinfo(
|
||||
infile, detailed_page_analysis, log=log)
|
||||
self._needs_rendering = pdf.root.get('/NeedsRendering', False)
|
||||
self._has_acroform = '/AcroForm' in pdf.root
|
||||
|
||||
|
||||
@@ -32,8 +32,8 @@ regex_remove_char_tags = re.compile(br"""
|
||||
""", re.VERBOSE)
|
||||
|
||||
|
||||
def _page_get_textblocks(infile, pageno, xmltext):
|
||||
"""Smarter text detection"""
|
||||
def page_get_textblocks(infile, pageno, xmltext, height):
|
||||
"""Get text boxes out of Ghostscript txtwrite xml"""
|
||||
|
||||
root = xmltext
|
||||
if not hasattr(xmltext, 'findall'):
|
||||
@@ -45,8 +45,10 @@ def _page_get_textblocks(infile, pageno, xmltext):
|
||||
font_size = span.attrib['size']
|
||||
pts = [int(pt) for pt in bbox_str.split()]
|
||||
pts[1] = pts[1] - int(float(font_size) + 0.5)
|
||||
bbox = tuple(pts)
|
||||
yield bbox
|
||||
bbox_topdown = tuple(pts)
|
||||
bb = bbox_topdown
|
||||
bbox_bottomup = (bb[0], height - bb[3], bb[2], height - bb[1])
|
||||
yield bbox_bottomup
|
||||
|
||||
def joined_blocks():
|
||||
prev = None
|
||||
@@ -55,7 +57,7 @@ def _page_get_textblocks(infile, pageno, xmltext):
|
||||
prev = bbox
|
||||
if bbox[1] == prev[1] and bbox[3] == prev[3]:
|
||||
gap = prev[2] - bbox[0]
|
||||
height = bbox[3] - bbox[1]
|
||||
height = abs(bbox[3] - bbox[1])
|
||||
if gap < height:
|
||||
# Join boxes
|
||||
prev = (prev[0], prev[1], bbox[2], bbox[3])
|
||||
|
||||
Reference in New Issue
Block a user