Refactor xy-pair for resolution to tuple
This commit is contained in:
+15
-18
@@ -201,12 +201,12 @@ def validate_pdfinfo_options(context):
|
||||
def get_page_dpi(pageinfo, options):
|
||||
"Get the DPI when nonsquare DPI is tolerable"
|
||||
xres = max(
|
||||
pageinfo.xres or VECTOR_PAGE_DPI,
|
||||
pageinfo.xyres[0] or VECTOR_PAGE_DPI,
|
||||
options.oversample or 0,
|
||||
VECTOR_PAGE_DPI if pageinfo.has_vector else 0,
|
||||
)
|
||||
yres = max(
|
||||
pageinfo.yres or VECTOR_PAGE_DPI,
|
||||
pageinfo.xyres[1] or VECTOR_PAGE_DPI,
|
||||
options.oversample or 0,
|
||||
VECTOR_PAGE_DPI if pageinfo.has_vector else 0,
|
||||
)
|
||||
@@ -215,8 +215,8 @@ def get_page_dpi(pageinfo, options):
|
||||
|
||||
def get_page_square_dpi(pageinfo, options):
|
||||
"Get the DPI when we require xres == yres, scaled to physical units"
|
||||
xres = pageinfo.xres or 0
|
||||
yres = pageinfo.yres or 0
|
||||
xres = pageinfo.xyres[0] or 0
|
||||
yres = pageinfo.xyres[1] or 0
|
||||
userunit = pageinfo.userunit or 1
|
||||
return float(
|
||||
max(
|
||||
@@ -232,8 +232,8 @@ def get_canvas_square_dpi(pageinfo, options):
|
||||
"""Get the DPI when we require xres == yres, in Postscript units"""
|
||||
return float(
|
||||
max(
|
||||
(pageinfo.xres) or VECTOR_PAGE_DPI,
|
||||
(pageinfo.yres) or VECTOR_PAGE_DPI,
|
||||
(pageinfo.xyres[0]) or VECTOR_PAGE_DPI,
|
||||
(pageinfo.xyres[1]) or VECTOR_PAGE_DPI,
|
||||
VECTOR_PAGE_DPI if pageinfo.has_vector else 0,
|
||||
options.oversample or 0,
|
||||
)
|
||||
@@ -321,9 +321,8 @@ def rasterize_preview(input_file, page_context):
|
||||
ghostscript.rasterize_pdf(
|
||||
input_file,
|
||||
output_file,
|
||||
xres=canvas_dpi,
|
||||
yres=canvas_dpi,
|
||||
raster_device='jpeggray',
|
||||
xyres=(canvas_dpi, canvas_dpi),
|
||||
page_dpi=(page_dpi, page_dpi),
|
||||
pageno=page_context.pageinfo.pageno + 1,
|
||||
)
|
||||
@@ -436,9 +435,8 @@ def rasterize(
|
||||
ghostscript.rasterize_pdf(
|
||||
input_file,
|
||||
output_file,
|
||||
xres=canvas_dpi,
|
||||
yres=canvas_dpi,
|
||||
raster_device=device,
|
||||
xyres=(canvas_dpi, canvas_dpi),
|
||||
page_dpi=(page_dpi, page_dpi),
|
||||
pageno=pageinfo.pageno + 1,
|
||||
rotation=correction,
|
||||
@@ -488,8 +486,7 @@ def create_ocr_image(image, page_context):
|
||||
# pink = ImageColor.getcolor('#ff0080', im.mode)
|
||||
draw = ImageDraw.ImageDraw(im)
|
||||
|
||||
xres, yres = im.info['dpi']
|
||||
log.debug('resolution %r %r' % (xres, yres))
|
||||
log.debug('resolution %r', im.info['dpi'])
|
||||
|
||||
if not options.force_ocr:
|
||||
# Do not mask text areas when forcing OCR, because we need to OCR
|
||||
@@ -505,12 +502,12 @@ def create_ocr_image(image, page_context):
|
||||
# without regard whatever resolution is in pageinfo (may differ or
|
||||
# be None)
|
||||
bbox = [float(v) for v in textarea]
|
||||
xscale, yscale = float(xres) / 72.0, float(yres) / 72.0
|
||||
xyscale = tuple(float(coord) / 72.0 for coord in im.info['dpi'])
|
||||
pixcoords = [
|
||||
bbox[0] * xscale,
|
||||
im.height - bbox[3] * yscale,
|
||||
bbox[2] * xscale,
|
||||
im.height - bbox[1] * yscale,
|
||||
bbox[0] * xyscale[0],
|
||||
im.height - bbox[3] * xyscale[1],
|
||||
bbox[2] * xyscale[0],
|
||||
im.height - bbox[1] * xyscale[1],
|
||||
]
|
||||
pixcoords = [int(round(c)) for c in pixcoords]
|
||||
log.debug('blanking %r', pixcoords)
|
||||
@@ -524,7 +521,7 @@ def create_ocr_image(image, page_context):
|
||||
|
||||
del draw
|
||||
# Pillow requires integer DPI
|
||||
dpi = round(xres), round(yres)
|
||||
dpi = tuple(round(coord) for coord in im.info['dpi'])
|
||||
im.save(output_file, dpi=dpi)
|
||||
return output_file
|
||||
|
||||
|
||||
@@ -135,32 +135,31 @@ def extract_text(input_file, pageno=1):
|
||||
def rasterize_pdf(
|
||||
input_file,
|
||||
output_file,
|
||||
xres,
|
||||
yres,
|
||||
*,
|
||||
raster_device,
|
||||
xyres,
|
||||
pageno=1,
|
||||
page_dpi=None,
|
||||
rotation=None,
|
||||
filter_vector=False,
|
||||
):
|
||||
"""Rasterize one page of a PDF at resolution (xres, yres) in canvas units.
|
||||
"""Rasterize one page of a PDF at resolution xyres in canvas units.
|
||||
|
||||
The image is sized to match the integer pixels dimensions implied by
|
||||
(xres, yres) even if those numbers are noninteger. The image's DPI will
|
||||
(xyres[0], xyres[1]) even if those numbers are noninteger. The image's DPI will
|
||||
be overridden with the values in page_dpi.
|
||||
|
||||
:param input_file: pathlike
|
||||
:param output_file: pathlike
|
||||
:param xres: resolution at which to rasterize page
|
||||
:param yres:
|
||||
:param raster_device:
|
||||
:param xyres: resolution at which to rasterize page
|
||||
:param pageno: page number to rasterize (beginning at page 1)
|
||||
:param page_dpi: resolution tuple (x, y) overriding output image DPI
|
||||
:param rotation: 0, 90, 180, 270: clockwise angle to rotate page
|
||||
:param filter_vector: if True, remove vector graphics objects
|
||||
:return:
|
||||
"""
|
||||
res = round(xres, 6), round(yres, 6)
|
||||
res = round(xyres[0], 6), round(xyres[1], 6)
|
||||
if not page_dpi:
|
||||
page_dpi = res
|
||||
|
||||
|
||||
@@ -356,12 +356,11 @@ class ImageInfo:
|
||||
return self._enc
|
||||
|
||||
@property
|
||||
def xres(self):
|
||||
return _get_dpi(self._shorthand, (self._width, self._height))[0]
|
||||
|
||||
@property
|
||||
def yres(self):
|
||||
return _get_dpi(self._shorthand, (self._width, self._height))[1]
|
||||
def xyres(self):
|
||||
return (
|
||||
_get_dpi(self._shorthand, (self._width, self._height))[0],
|
||||
_get_dpi(self._shorthand, (self._width, self._height))[1],
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
class_locals = {
|
||||
@@ -371,7 +370,7 @@ class ImageInfo:
|
||||
}
|
||||
return (
|
||||
"<ImageInfo '{name}' {type_} {width}x{height} {color} "
|
||||
"{comp} {bpc} {enc} {xres}x{yres}>"
|
||||
"{comp} {bpc} {enc} {xyres}>"
|
||||
).format(**class_locals)
|
||||
|
||||
|
||||
@@ -607,9 +606,9 @@ def _pdf_get_pageinfo(pdf, pageno: int, infile: PathLike, xmltext: str):
|
||||
|
||||
pageinfo['images'] = [im for im in contentsinfo if isinstance(im, ImageInfo)]
|
||||
if pageinfo['images']:
|
||||
xres = Decimal(max(image.xres for image in pageinfo['images']))
|
||||
yres = Decimal(max(image.yres for image in pageinfo['images']))
|
||||
pageinfo['xres'], pageinfo['yres'] = xres, yres
|
||||
xres = Decimal(max(image.xyres[0] for image in pageinfo['images']))
|
||||
yres = Decimal(max(image.xyres[1] for image in pageinfo['images']))
|
||||
pageinfo['xyres'] = xres, yres
|
||||
pageinfo['width_pixels'] = int(round(xres * pageinfo['width_inches']))
|
||||
pageinfo['height_pixels'] = int(round(yres * pageinfo['height_inches']))
|
||||
|
||||
@@ -679,11 +678,11 @@ class PageInfo:
|
||||
|
||||
@property
|
||||
def width_pixels(self):
|
||||
return int(round(self.width_inches * self.xres))
|
||||
return int(round(self.width_inches * self.xyres[0]))
|
||||
|
||||
@property
|
||||
def height_pixels(self):
|
||||
return int(round(self.height_inches * self.yres))
|
||||
return int(round(self.height_inches * self.xyres[1]))
|
||||
|
||||
@property
|
||||
def rotation(self):
|
||||
@@ -723,12 +722,8 @@ class PageInfo:
|
||||
)
|
||||
|
||||
@property
|
||||
def xres(self):
|
||||
return self._pageinfo.get('xres', None)
|
||||
|
||||
@property
|
||||
def yres(self):
|
||||
return self._pageinfo.get('yres', None)
|
||||
def xyres(self):
|
||||
return self._pageinfo.get('xyres', (0, 0))
|
||||
|
||||
@property
|
||||
def userunit(self):
|
||||
@@ -743,14 +738,13 @@ class PageInfo:
|
||||
|
||||
def __repr__(self):
|
||||
return (
|
||||
'<PageInfo ' 'pageno={} {}"x{}" rotation={} res={}x{} has_text={}>'
|
||||
'<PageInfo ' 'pageno={} {}"x{}" rotation={} res={} has_text={}>'
|
||||
).format(
|
||||
self.pageno,
|
||||
self.width_inches,
|
||||
self.height_inches,
|
||||
self.rotation,
|
||||
self.xres,
|
||||
self.yres,
|
||||
self.xyres,
|
||||
self.has_text,
|
||||
)
|
||||
|
||||
|
||||
@@ -76,9 +76,8 @@ def test_rasterize_size(francais, outdir, caplog):
|
||||
rasterize_pdf(
|
||||
path,
|
||||
outdir / 'out.png',
|
||||
target_size[0] / page_size[0],
|
||||
target_size[1] / page_size[1],
|
||||
raster_device='pngmono',
|
||||
xyres=(target_size[0] / page_size[0], target_size[1] / page_size[1]),
|
||||
page_dpi=forced_dpi,
|
||||
)
|
||||
|
||||
@@ -99,9 +98,8 @@ def test_rasterize_rotated(francais, outdir, caplog):
|
||||
rasterize_pdf(
|
||||
path,
|
||||
outdir / 'out.png',
|
||||
target_size[0] / page_size[0],
|
||||
target_size[1] / page_size[1],
|
||||
raster_device='pngmono',
|
||||
xyres=(target_size[0] / page_size[0], target_size[1] / page_size[1]),
|
||||
page_dpi=forced_dpi,
|
||||
rotation=90,
|
||||
)
|
||||
|
||||
+4
-4
@@ -74,8 +74,8 @@ def test_oversample(spoof_tesseract_cache, renderer, resources, outpdf):
|
||||
|
||||
pdfinfo = PdfInfo(oversampled_pdf)
|
||||
|
||||
print(pdfinfo[0].xres)
|
||||
assert abs(pdfinfo[0].xres - 350) < 1
|
||||
print(pdfinfo[0].xyres[0])
|
||||
assert abs(pdfinfo[0].xyres[0] - 350) < 1
|
||||
|
||||
|
||||
def test_repeat_ocr(resources, no_outpdf):
|
||||
@@ -393,8 +393,8 @@ def test_very_high_dpi(spoof_tesseract_cache, resources, outpdf):
|
||||
pdfinfo = PdfInfo(outpdf)
|
||||
|
||||
image = pdfinfo[0].images[0]
|
||||
assert isclose(image.xres, image.yres)
|
||||
assert isclose(image.xres, 2400)
|
||||
assert isclose(image.xyres[0], image.xyres[1])
|
||||
assert isclose(image.xyres[0], 2400)
|
||||
|
||||
|
||||
def test_overlay(spoof_tesseract_noop, resources, outpdf):
|
||||
|
||||
@@ -43,7 +43,7 @@ def test_mono_not_inverted(resources, outdir):
|
||||
opt.main(infile, outdir / 'out.pdf', level=3)
|
||||
|
||||
rasterize_pdf(
|
||||
outdir / 'out.pdf', outdir / 'im.png', xres=10, yres=10, raster_device='pnggray'
|
||||
outdir / 'out.pdf', outdir / 'im.png', raster_device='pnggray', xyres=(10, 10)
|
||||
)
|
||||
|
||||
with Image.open(fspath(outdir / 'im.png')) as im:
|
||||
|
||||
@@ -85,8 +85,8 @@ def test_single_page_image(outdir):
|
||||
assert pdfimage.color == Colorspace.gray
|
||||
|
||||
# DPI in a 1"x1" is the image width
|
||||
assert isclose(pdfimage.xres, 8)
|
||||
assert isclose(pdfimage.yres, 8)
|
||||
assert isclose(pdfimage.xyres[0], 8)
|
||||
assert isclose(pdfimage.xyres[1], 8)
|
||||
|
||||
|
||||
def test_single_page_inline_image(outdir):
|
||||
@@ -105,7 +105,7 @@ def test_single_page_inline_image(outdir):
|
||||
info = pdfinfo.PdfInfo(filename)
|
||||
print(info)
|
||||
pdfimage = info[0].images[0]
|
||||
assert isclose(pdfimage.xres, 8)
|
||||
assert isclose(pdfimage.xyres[0], 8)
|
||||
assert pdfimage.color == Colorspace.gray
|
||||
assert pdfimage.width == 8
|
||||
|
||||
@@ -117,7 +117,7 @@ def test_jpeg(resources, outdir):
|
||||
|
||||
pdfimage = pdf[0].images[0]
|
||||
assert pdfimage.enc == Encoding.jpeg
|
||||
assert isclose(pdfimage.xres, 150)
|
||||
assert isclose(pdfimage.xyres[0], 150)
|
||||
|
||||
|
||||
def test_form_xobject(resources):
|
||||
@@ -139,7 +139,7 @@ def test_no_contents(resources):
|
||||
def test_oversized_page(resources):
|
||||
pdf = pdfinfo.PdfInfo(resources / 'poster.pdf')
|
||||
image = pdf[0].images[0]
|
||||
assert image.width * image.xres > 200, "this is supposed to be oversized"
|
||||
assert image.width * image.xyres[0] > 200, "this is supposed to be oversized"
|
||||
|
||||
|
||||
def test_pickle(resources):
|
||||
|
||||
@@ -50,12 +50,7 @@ def test_deskew(spoof_tesseract_noop, resources, outdir):
|
||||
deskewed_png = outdir / 'deskewed.png'
|
||||
|
||||
ghostscript.rasterize_pdf(
|
||||
deskewed_pdf,
|
||||
deskewed_png,
|
||||
xres=150,
|
||||
yres=150,
|
||||
raster_device='pngmono',
|
||||
pageno=1,
|
||||
deskewed_pdf, deskewed_png, raster_device='pngmono', xyres=(150, 150), pageno=1
|
||||
)
|
||||
|
||||
pix = Pix.open(deskewed_png)
|
||||
@@ -82,7 +77,7 @@ def test_remove_background(spoof_tesseract_noop, resources, outdir):
|
||||
output_png = outdir / 'remove_bg.png'
|
||||
|
||||
ghostscript.rasterize_pdf(
|
||||
output_pdf, output_png, xres=100, yres=100, raster_device='png16m', pageno=1
|
||||
output_pdf, output_png, raster_device='png16m', xyres=(100, 100), pageno=1
|
||||
)
|
||||
|
||||
# The output image should contain pure white and black
|
||||
@@ -122,7 +117,7 @@ def test_exotic_image(
|
||||
def test_non_square_resolution(renderer, spoof_tesseract_cache, resources, outpdf):
|
||||
# Confirm input image is non-square resolution
|
||||
in_pageinfo = PdfInfo(resources / 'aspect.pdf')
|
||||
assert in_pageinfo[0].xres != in_pageinfo[0].yres
|
||||
assert in_pageinfo[0].xyres[0] != in_pageinfo[0].xyres[1]
|
||||
|
||||
check_ocrmypdf(
|
||||
resources / 'aspect.pdf',
|
||||
@@ -135,8 +130,7 @@ def test_non_square_resolution(renderer, spoof_tesseract_cache, resources, outpd
|
||||
out_pageinfo = PdfInfo(outpdf)
|
||||
|
||||
# Confirm resolution was kept the same
|
||||
assert in_pageinfo[0].xres == out_pageinfo[0].xres
|
||||
assert in_pageinfo[0].yres == out_pageinfo[0].yres
|
||||
assert in_pageinfo[0].xyres == out_pageinfo[0].xyres
|
||||
|
||||
|
||||
@pytest.mark.parametrize('renderer', RENDERERS)
|
||||
@@ -145,7 +139,7 @@ def test_convert_to_square_resolution(
|
||||
):
|
||||
# Confirm input image is non-square resolution
|
||||
in_pageinfo = PdfInfo(resources / 'aspect.pdf')
|
||||
assert in_pageinfo[0].xres != in_pageinfo[0].yres
|
||||
assert in_pageinfo[0].xyres[0] != in_pageinfo[0].xyres[1]
|
||||
|
||||
# --force-ocr requires means forced conversion to square resolution
|
||||
check_ocrmypdf(
|
||||
@@ -162,7 +156,7 @@ def test_convert_to_square_resolution(
|
||||
in_p0, out_p0 = in_pageinfo[0], out_pageinfo[0]
|
||||
|
||||
# Resolution show now be equal
|
||||
assert out_p0.xres == out_p0.yres
|
||||
assert out_p0.xyres[0] == out_p0.xyres[1]
|
||||
|
||||
# Page size should match input page size
|
||||
assert isclose(in_p0.width_inches, out_p0.width_inches)
|
||||
@@ -170,7 +164,7 @@ def test_convert_to_square_resolution(
|
||||
|
||||
# Because we rasterized the page to produce a new image, it should occupy
|
||||
# the entire page
|
||||
out_im_w = out_p0.images[0].width / out_p0.images[0].xres
|
||||
out_im_h = out_p0.images[0].height / out_p0.images[0].yres
|
||||
out_im_w = out_p0.images[0].width / out_p0.images[0].xyres[0]
|
||||
out_im_h = out_p0.images[0].height / out_p0.images[0].xyres[1]
|
||||
assert isclose(out_p0.width_inches, out_im_w)
|
||||
assert isclose(out_p0.height_inches, out_im_h)
|
||||
|
||||
@@ -58,9 +58,8 @@ def check_monochrome_correlation(
|
||||
ghostscript.rasterize_pdf(
|
||||
pdf,
|
||||
png,
|
||||
xres=100,
|
||||
yres=100,
|
||||
raster_device='pngmono',
|
||||
xyres=(100, 100),
|
||||
pageno=pageno,
|
||||
rotation=0,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user