Partially solve ghostscript rasterize_pdf producing wrong file size
Kludge. Assumes JPEG for now. Messy.
This commit is contained in:
@@ -7,8 +7,10 @@ from shutil import copy
|
||||
from functools import lru_cache
|
||||
import re
|
||||
import sys
|
||||
from math import isclose
|
||||
from . import get_program
|
||||
from ..exceptions import SubprocessOutputError
|
||||
from PIL import Image
|
||||
|
||||
|
||||
@lru_cache(maxsize=1)
|
||||
@@ -33,8 +35,22 @@ def _gs_error_reported(stream):
|
||||
return re.search(r'error', stream, flags=re.IGNORECASE)
|
||||
|
||||
|
||||
def _correct_image_size(input_fp, output_file, res, int_res, log):
|
||||
# If the output size was reduced due to rounding DPI to an
|
||||
# integer, resize the image to its expected size
|
||||
input_fp.seek(0)
|
||||
with Image.open(input_fp) as im:
|
||||
expected_size = round(res[0] / int_res[0] * im.size[0]), \
|
||||
round(res[1] / int_res[1] * im.size[1])
|
||||
log.info(im.size)
|
||||
log.info(expected_size)
|
||||
im.resize(expected_size).save(output_file)
|
||||
|
||||
|
||||
def rasterize_pdf(input_file, output_file, xres, yres, raster_device, log,
|
||||
pageno=1):
|
||||
res = xres, yres
|
||||
int_res = round(xres), round(yres)
|
||||
with NamedTemporaryFile(delete=True) as tmp:
|
||||
args_gs = [
|
||||
get_program('gs'),
|
||||
@@ -46,7 +62,7 @@ def rasterize_pdf(input_file, output_file, xres, yres, raster_device, log,
|
||||
'-dFirstPage=%i' % pageno,
|
||||
'-dLastPage=%i' % pageno,
|
||||
'-o', tmp.name,
|
||||
'-r{0}x{1}'.format(str(round(xres)), str(round(yres))),
|
||||
'-r{0}x{1}'.format(str(int_res[0]), str(int_res[1])),
|
||||
input_file
|
||||
]
|
||||
|
||||
@@ -58,7 +74,13 @@ def rasterize_pdf(input_file, output_file, xres, yres, raster_device, log,
|
||||
log.debug(p.stdout)
|
||||
|
||||
if p.returncode == 0:
|
||||
copy(tmp.name, output_file)
|
||||
if isclose(int_res[0], res[0], abs_tol=0.1) and \
|
||||
isclose(int_res[1], res[1], abs_tol=0.1):
|
||||
copy(tmp.name, output_file)
|
||||
else:
|
||||
# If the output size was reduced due to rounding DPI to an
|
||||
# integer, resize the image to its expected size
|
||||
_correct_image_size(tmp, output_file, res, int_res, log)
|
||||
else:
|
||||
log.error('Ghostscript rasterizing failed')
|
||||
raise SubprocessOutputError()
|
||||
|
||||
@@ -445,10 +445,10 @@ def rasterize_with_ghostscript(
|
||||
# Ghostscript respects /UserUnit when rasterizing. Rasterize at
|
||||
# the true DPI but rewrite the output image to the working DPI.
|
||||
ghostscript.rasterize_pdf(
|
||||
input_file, output_file + '.tmp', xres=true_dpi, yres=true_dpi,
|
||||
input_file, output_file + '.jpg', xres=true_dpi, yres=true_dpi,
|
||||
raster_device=device, log=log)
|
||||
|
||||
with Image.open(output_file + ".tmp") as im:
|
||||
with Image.open(output_file + ".jpg") as im:
|
||||
im.save(output_file, dpi=(working_dpi, working_dpi))
|
||||
|
||||
|
||||
|
||||
@@ -39,3 +39,13 @@ def poster(resources):
|
||||
def test_userunit_ghostscript_fails(poster, no_outpdf):
|
||||
p, out, err = run_ocrmypdf(poster, no_outpdf, '--output-type=pdfa')
|
||||
assert p.returncode == ExitCode.input_file
|
||||
|
||||
|
||||
def test_userunit_qpdf_passes(spoof_tesseract_cache, poster, outpdf):
|
||||
before = PdfInfo(poster)
|
||||
check_ocrmypdf(poster, outpdf, '--output-type=pdf',
|
||||
env=spoof_tesseract_cache)
|
||||
|
||||
after = PdfInfo(outpdf)
|
||||
assert isclose(before[0].width_inches, after[0].width_inches)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user