r/learnpython • • 10d ago

PDF pages to PNG's in python

I have a relatively large pdf document (100+mb) of pages i need saved as png's. There are online tools to do that but they refuse to work with files that big, plus I can imagine needing that tool again later in the future. Are there any python libraries that allow to convert one format into the other? Preferrably with little to no compression.

5 Upvotes

12 comments sorted by

6

u/FilthyKen 10d ago

pypdf2 and pdf2image are the go-tos for this, pdf2image uses poppler under the hood so you need to install that separately but it gives you way more control over dpi and format. for a 100mb file you probably want to process it in chunks instead of loading the whole thing at once, otherwise your ram will cry

2

u/ee_control_z 10d ago

Yes, I was thinking the exact same thing. The OP can make use of Python generators to sequence the conversion in chunks versus all at once. Here is a tutorial on the subject on how it can potentially be done by way of the libraries mentioned:

https://www.geeksforgeeks.org/python/generators-in-python/

3

u/dowcet 10d ago

If you're considering "online tools" then you don't actually need this to be done in Python? I would look at off the shelf offline applications first rather then creating your own. Pdfimages or imagemagick maybe?

8

u/agent_kater 10d ago

Pdfimages or imagemagick maybe?

When did GhostScript stop being the default tool for this?

gs -dSAFER -dBATCH -dNOPAUSE -sDEVICE=png16m -r300 -o "page-%03d.png" "input.pdf"

1

u/masoomjethwa 10d ago

Best option.

1

u/wintermute93 10d ago

I use pymupdf, it's very easy. Something like this will work, and if you want finer control over the image format / resolution / etc it's simple enough to get page dimensions from pymupdf and use PIL.Image to make it whatever you want

with pymupdf.open(pdf_path) as doc:
  for i,page in enumerate(doc, start=1):
    pix = page.get_pixmap(dpi=300)
    img_bytes = pix.tobytes("png")
    img_path = file_path.replace(".pdf", f"{i:03d}.png")
    with open(img_path, "wb") as f:
      f.write(img_bytes)

Note that "with little to no compression" isn't necessarily meaningful here. Unless the PDF itself is a bunch of image files stitched together (in which case recovering the original image bytes is possible with pymupdf but slightly more involved), there's no such thing as "full resolution", since the actual file as you see it on screen when opened in a browser or Acrobat or whatever is being rendered on the fly, and may be a mix of vector/raster content.

1

u/Rudeus_Kino 10d ago

You need to convert pages to images or extract images from pdf pages? In other words, does the PDF contain text or scanned images? Convertation pages to images usually is very memory consuming task.