Add PDF linearization
This commit is contained in:
@@ -716,6 +716,13 @@ def convert_to_pdfa(input_pdf, input_ps_stub, context):
|
||||
return output_file
|
||||
|
||||
|
||||
def should_linearize(working_file, context):
|
||||
filesize = os.stat(working_file).st_size
|
||||
if filesize > (context.options.fast_web_view * 1_000_000):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def metadata_fixup(working_file, context):
|
||||
output_file = context.get_path('metafix.pdf')
|
||||
options = context.options
|
||||
@@ -749,11 +756,14 @@ def metadata_fixup(working_file, context):
|
||||
context.log.info(
|
||||
"The following metadata fields were not copied: %r", not_copied
|
||||
)
|
||||
|
||||
pdf.save(
|
||||
output_file,
|
||||
compress_streams=True,
|
||||
preserve_pdfa=True,
|
||||
object_stream_mode=pikepdf.ObjectStreamMode.generate,
|
||||
linearize=( # Don't linearize if optimize() will be linearizing too
|
||||
should_linearize(working_file, context) if options.optimize == 0 else False
|
||||
),
|
||||
)
|
||||
original.close()
|
||||
pdf.close()
|
||||
@@ -762,7 +772,13 @@ def metadata_fixup(working_file, context):
|
||||
|
||||
def optimize_pdf(input_file, context):
|
||||
output_file = context.get_path('optimize.pdf')
|
||||
optimize(input_file, output_file, context)
|
||||
save_settings = dict(
|
||||
compress_streams=True,
|
||||
preserve_pdfa=True,
|
||||
object_stream_mode=pikepdf.ObjectStreamMode.generate,
|
||||
linearize=should_linearize(input_file, context),
|
||||
)
|
||||
optimize(input_file, output_file, context, save_settings)
|
||||
return output_file
|
||||
|
||||
|
||||
|
||||
@@ -196,6 +196,7 @@ def ocr( # pylint: disable=unused-argument
|
||||
pdfa_image_compression=None,
|
||||
user_words=None,
|
||||
user_patterns=None,
|
||||
fast_web_view=None,
|
||||
keep_temporary_files=None,
|
||||
progress_bar=None,
|
||||
tesseract_env=None,
|
||||
|
||||
@@ -466,6 +466,18 @@ advanced.add_argument(
|
||||
metavar='FILE',
|
||||
help="Specify the location of the Tesseract user patterns file.",
|
||||
)
|
||||
advanced.add_argument(
|
||||
'--fast-web-view',
|
||||
type=numeric(float, 0),
|
||||
default=1.0,
|
||||
metavar="MEGABYTES",
|
||||
help="If the size of file is more than this threshold (in MB), then "
|
||||
"linearize the PDF for fast web viewing. This allows the PDF to be "
|
||||
"displayed before it is fully downloaded in web browsers, but increases "
|
||||
"the space required slightly. By default we skip this for small files "
|
||||
"which do not benefit. If the threshold is 0 it will be apply to all files. "
|
||||
"Set the threshold very high to disable.",
|
||||
)
|
||||
|
||||
debugging = parser.add_argument_group(
|
||||
"Debugging", "Arguments to help with troubleshooting and debugging"
|
||||
|
||||
@@ -449,7 +449,7 @@ def transcode_pngs(pike, images, image_name_fn, root, log, options):
|
||||
im_obj.write(compdata.read(), filter=Name.FlateDecode, decode_parms=dparms)
|
||||
|
||||
|
||||
def optimize(input_file, output_file, context):
|
||||
def optimize(input_file, output_file, context, save_settings):
|
||||
log = context.log
|
||||
options = context.options
|
||||
if options.optimize == 0:
|
||||
@@ -479,11 +479,7 @@ def optimize(input_file, output_file, context):
|
||||
|
||||
target_file = Path(output_file).with_suffix('.opt.pdf')
|
||||
pike.remove_unreferenced_resources()
|
||||
pike.save(
|
||||
target_file,
|
||||
preserve_pdfa=True,
|
||||
object_stream_mode=pikepdf.ObjectStreamMode.generate,
|
||||
)
|
||||
pike.save(target_file, **save_settings)
|
||||
|
||||
input_size = Path(input_file).stat().st_size
|
||||
output_size = Path(target_file).stat().st_size
|
||||
@@ -497,8 +493,11 @@ def optimize(input_file, output_file, context):
|
||||
log.info(f"Optimize ratio: {ratio:.2f} savings: {(100 * savings):.1f}%")
|
||||
|
||||
if savings < 0:
|
||||
log.info("Optimize did not improve the file - discarded")
|
||||
re_symlink(input_file, output_file)
|
||||
log.info("Image optimization did not improve the file - discarded")
|
||||
# We still need to save the file
|
||||
with pikepdf.open(input_file) as pike:
|
||||
pike.remove_unreferenced_resources()
|
||||
pike.save(output_file, **save_settings)
|
||||
else:
|
||||
re_symlink(target_file, output_file)
|
||||
|
||||
@@ -535,7 +534,16 @@ def main(infile, outfile, level, jobs=1):
|
||||
with TemporaryDirectory() as td:
|
||||
context = PDFContext(options, td, infile, None)
|
||||
tmpout = Path(td) / 'out.pdf'
|
||||
optimize(infile, tmpout, context)
|
||||
optimize(
|
||||
infile,
|
||||
tmpout,
|
||||
context,
|
||||
dict(
|
||||
compress_streams=True,
|
||||
preserve_pdfa=True,
|
||||
object_stream_mode=pikepdf.ObjectStreamMode.generate,
|
||||
),
|
||||
)
|
||||
copy(fspath(tmpout), fspath(outfile))
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user