DEV Community

AsyncMonk
AsyncMonk

Posted on

The ZIP of images from a PDF has no page numbers, so I rebuild them


A kind of small web job I see a lot: build a simple product site, and the only place the product photos exist is a brochure PDF someone exported from a design tool years ago. Screenshotting each page and cropping is what people usually do first, and it gets you pictures at whatever size the brochure happened to display them. Before I'd take on a job like that I wanted a repeatable way to go from one PDF to a folder of usable original files, so I built a test brochure and ran it end to end. It's my own file, generated with reportlab: 8 pages for a made-up brand called LEAF CO, with a logo in the top-right corner of every page, four product shots (two JPEGs, one PNG with transparency, one flat PNG), page 7 repeating all four, and page 6 drawn as a vector flowchart and bar chart. Everything below comes from that file. This is the checklist I ended up with.

  1. Count what the PDF stores, not what the pages show. My brochure has 17 image placements across 8 pages, but only 5 distinct image objects, because the logo is the same object painted 8 times and each product shot is reused on page 7. ImgIng's Extract PDF images returned exactly 5 results, 693 KB in total. The logo came out once, not eight times, and its card lists every page it sits on. That list is long enough that the card cuts it off after page 5 with an ellipsis; the full text "Page 1, Page 2, … Page 8" is in the page, you just can't read it on the card. If I'm quoting a job, "5 files" is the honest scope, not "17 images".

Extract PDF images on my 8-page test brochure: 5 results, named q008-brochure-image-001 to 005 (self-made file; its page titles are in Chinese)

  1. The ZIP forgets the page numbers, so rebuild them. The download is q008-brochure-images.zip with five files sitting flat inside, q008-brochure-image-001.png to -005.png, stored without compression, no folders. The page numbers exist only on the cards in the browser. For a client handover I want a sheet that says which file is on which page, so I rebuild the map from the PDF by matching pixel sizes. A short PyMuPDF pass lists every image object on every page with its width and height and groups them by size. Then it opens each extracted file and looks up its dimensions: if exactly one object has that size, the file gets that object's page list, and if two different objects share it, the row says "check by eye" instead. On the brochure all five files matched. The 360×120 logo is on pages 1 through 8, the 1000×1000 JPEG on 1, 2 and 7, the 1200×900 JPEG on 3 and 7, and the two PNGs (800×800 and 900×600) on 4 and 7 and on 5 and 7. That goes into a small CSV of file, size and pages, which travels with the images.

Pairing by size is cheap and it's enough here because every image has its own dimensions. A real brochure with a row of identical 800×800 thumbnails would hit the "check by eye" branch, and I'd rather it say so than guess.

  1. Check that what you got is the original, once, then stop worrying. I had the source images since I made the brochure, so I compared. Both JPEG product shots had the same SHA-256 as the files I embedded. The PNGs matched pixel for pixel, including the transparent one, whose alpha survived. One quirk: all three PNGs came back as RGBA, including the logo and the flat shot that went in as plain RGB; they just gained a fully opaque alpha channel. Harmless for a website, worth knowing if something downstream complains about an alpha channel.

  2. Vector pages give you nothing, and that's correct. Page 6 is a flowchart and a bar chart drawn with lines and rectangles, not a bitmap. The only thing it contributed was the logo in its corner. If that chart is wanted on the new site, it's either a page render (the PDF to images mode on the same workspace, 216 DPI gives 1786×2526 for an A4 page) or, better, asking whoever made the brochure for the source file.

  3. One PDF per run. The file picker only accepts one file. When I dragged two PDFs onto the drop zone together, it loaded the first one (the brochure showed up as 8 pages, 740 KB) and ignored the second without saying anything. If a job comes with a dozen brochures, that's a dozen runs, and I'd write the file names down as I go because nothing on screen tells you the second one was skipped. Loading a new file does warn that the current work gets replaced once you confirm.

  4. More than one result means ZIP only. There's no save button on individual cards. With a single result the button changes to "Save this image" and writes that file directly; with five you get "Save extracted images (ZIP)" and pick from the unpacked folder afterwards. I haven't tried right-click saving from the card thumbnails, so I can't say whether that gives you the full file.

That's the whole routine: count objects, extract, rebuild the page map, spot-check, and flag vector pages. The workspace I used for the extraction is at https://imging.ai/ and it doesn't need an account.

Top comments (0)