I often use a command like this:
$ pdfjam --a4paper -o "$pdf" "$png"
The input png file is 105kb and the resulting pdf is 97kb. The beauty and strength of pdfjam is that it uses pdfpages to simply insert images as they are without manipulation (whereas most other tools such as ImageMagick insist on transcoding images).
So what explains the fact that the output is smaller? If some kind of non-lossy compression is used within the PDF container, the PNG should not be that significantly compressable, I would think. Otherwise that would imply a notable inefficiency in the png algorithm.
I don’t know about compression on the PDF side, but PNG uses deflate compression, which, according to https://www.libpng.org/pub/png/book/chapter09.html#png.ch09.div.2 is “not the best-compressing algorithm known” (that’s taken slightly out of context, it definitely is not bad). Also according to that chapter, most PNG implementations use zlib, which supports different compression levels. So the PDF container might have a way of compressing it slightly better, considering that 97/105 is not that good of a compression ratio.
You could try opening the image with an image editor that exposes the different compression levels (GIMP and Krita come to mind) and see, whether you can compress it further
Thanks! I did not realize there were different compression levels. So I discovered optipng. If I scan to PBM, that can be fed into optipng set for max compression:
$ convert sample_scan.pbm sample_IM.png; # ImageMagick for comparison $ optipng -out sample_optipng_default.png sample_scan.pbm; # run with defaults (moderate effort, -o2) $ optipng --strip all -o7 -out sample_optipng_min.png sample_scan.pbm; # max effort (smallest result) $ pdfjam --a4paper -o sample_optipng_min.pdf sample_optipng_min.png $ cjb2 -lossless sample_scan.pbm sample_lossless.djvu; # DjVu for comparison $ du -h … 24K sample_lossless.djvu 68K sample_optipng_min.png 68K sample_optipng_default.png 72K sample_optipng_min.pdf 80K sample_IM.pngThe tightest PNG compression w/metadata stripped (or even just the optipng default) is much smaller than ImageMagick’s output. The PDF produced by
pdfjamis bigger than the png it contains (rightfully so). So I’m pleased with this. I’ll replace ImageMagic withoptipng. And if a scanned doc is just 1 page, I won’t even bother with pdfjam and just keep the png.I thought PNG was inherently lossless but the
pngquanttool proves there is a lossy compression algo. Although I suppose anything can be lossy with image processing done independently. I did not fiddle withpngquantbecause it seems to only be relevant to color reduction, which makes no sense on a bitonal image.DjVu is a clear winner. ⅓ the size and still lossless. But there is no LaTeX pkg for DjVu so the smaller size obviously comes with a big trade off. But then we must consider that a DjVu file can be directly converted to PDF (LaTeX importable) using
ddjvu. So we have:$ ddjvu -format=pdf -quality=150 sample_lossless.djvu sample_ddjvu_lossless.pdf; # 150→highest possible quality $ pdfimages -all sample_ddjvu_lossless.pdf innards; # because we want to see what’s inside that thing $ du -h … 24K sample_lossless.djvu 44K sample_ddjvu_lossless.pdf 44K innards-000.ccitt 4.0K innards-000.params $ cat innards-000.params; # to get an idea of what the CCITT is (fax or whatever) -4 -P -X 2464 -B -MThe PDF size (from DjVu) is still smaller than the smallest PNG. And we can see that
ddjvudid not do anything foolish like stuff a jpg in the PDF. It’s not fun to work with CCITT files, but I suppose that would be rare. In the end, DjVu seems like a winner for archiving becauseddjvucan always make a PDF that is still smaller than a PNG, and LaTeX can work with that.Very interesting, thanks for the write-up!
Just as an aside, but you also noted it yourself
I thought PNG was inherently lossless but the pngquant tool proves there is a lossy compression algo.
PNG itself is lossless, it’s just that
pngquant“manipulates” the image to be better compressible.And I didn’t know about DjVu at all, that’s really good to know!


