Skip to content

Instantly share code, notes, and snippets.

@finevine
Last active January 13, 2023 13:42
Show Gist options
  • Save finevine/ee0750a275ea829ded959dc88c85400d to your computer and use it in GitHub Desktop.
Save finevine/ee0750a275ea829ded959dc88c85400d to your computer and use it in GitHub Desktop.
"""Compute with pike-pdf color."""
import os
from PIL import Image
from pikepdf import Pdf, PdfImage, Name
import zlib
# input_file_path = "108.pdf"
output_file_path = "_pike_pdf.pdf"
resize_factor = 0.5
convert_to_gray_scale = True
example = Pdf.open(input_file_path, allow_overwriting_input=True)
computed_images: list[str] = []
# Grab all the pages and all the images in every page.
for page in example.pages:
if imagelists := list(page.images.keys()):
for image in imagelists:
rawimage = page.images[image]
# compute images > 300kB
if rawimage.Length > 50000 and image not in computed_images:
computed_images.append(image)
pdfimage = PdfImage(rawimage)
pillowimage = pdfimage.as_pil_image()
width, height = pillowimage.size
width, height = int(width * resize_factor), int(height * resize_factor)
if (height, width) != (0,0):
pillowimage = pillowimage.resize((width, height), Image.HAMMING)
if convert_to_gray_scale:
pillowimage = pillowimage.convert('L')
rawimage.write(zlib.compress(pillowimage.tobytes()), filter=Name("/FlateDecode"))
rawimage.ColorSpace = Name("/DeviceGray")
rawimage.Width, rawimage.Height = width, height
example.save(output_file_path)
initial_size = os.path.getsize(input_file_path)
final_size = os.path.getsize(output_file_path)
ratio = 1 - (final_size / initial_size)
print("Compression by {0:.0%}.".format(ratio))
print("Final file size with pike is {0:.1f}MB".format(final_size / 1000000))
print("Done.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment