Finding Image Bloat In Binary Files

I’ve previously talked about using PNGDistill to optimize batches of images, but in today’s quick post, I’d like to show how you can use the tool to check whether images in your software binaries are well optimized.

For instance, consider Chrome. Chrome uses a lot of PNGs, all mashed together a single resources.pak file. Tip: Search for files for the string IEND to find embedded PNG files.

With Fiddler installed, go to a command prompt and enter the following commands:

cd %USERPROFILE%\AppData\Local\Google\Chrome SxS\Application\60.0.3079.0
mkdir temp
copy resources.pak temp
cd temp
"C:\Program Files (x86)\Fiddler2\tools\PngDistill.exe" resources.pak grovel
for /f "delims=|" %f in ('dir /b *.png') do "c:\program files (x86)\fiddler2\tools\pngdistill" "%f" log

You now have a PNGDistill.LOG file showing the results. Open it in a CSV viewer like Excel or Google Sheets. You can see that Chrome is pretty well-optimized, with under 3% bloat.

image

Let’s take a look at Brave, which uses electron_resources.pak:

image

Brave does even better! Firefox has images in a few different files; I found a bunch in a file named omni.ja:

image

The picture gets less rosy elsewhere though. Microsoft’s MFC140u.dll’s images are 7% bloat:

image

Windows’ Shell32.dll uses poor compression:

image

Windows’ ImageRes.dll has over 5 megabytes (nearly 20% of image weight) bloat:

image

And the Windows 10’s ApplicationFrame.dll is well-compressed, but the images have nearly 87% metadata bloat:

image

Does ImageBloat Matter?

Well, yes, it does. Even when software isn’t distributed by webpages, image bloat still takes up precious space on your disk (which might be limited in the case of a SSD) and it burns cycles and memory to process or discard unneeded metadata.

Optimize your images. Make it automatic via your build process and test your binaries to make sure it’s working as expected.

-Eric

PS: Rafael Rivera wrote a graphical tool for finding metadata bloat in binaries; check it out.

PPS: I ran PNGDistill against all of the PNGs embedded in EXE/DLLs in the Windows\System32 folder. 33mb * 270M devices = 8.9 petabytes of wasted storage for imagebloat in system32 alone.  Raw Data:

Finding Image Bloat In Binary Files

Photoshop and Save For Web

Adobe recently announced that “Save for Web” in Photoshop is a “legacy feature” which won’t be improved. I decided to have a look at Adobe Photoshop CC (2015.0.0 Release 20150529.r88 x64) to see the impact of its many different “save” commands on the resulting file size.

First, I created a trivial 20×20 image and drew a red dot in the middle of it.

Next, I performed the naïve File > Save As > PNG operation. The output is a 16,723 byte PNG file, 97% of which is Adobe metadata:

image

If I instead use File > Export > Quick Export as PNG, the result is a 571 byte PNG that can be shrunk by 35 bytes to 536 using the Zopfli compressor:

image

If I instead click File > Export > Export As > PNG, the default size is 608 bytes:

image

If I untick the “Transparency” checkbox:

image

…the file grows to 662 bytes. Interestingly, however, when I retick that same box, the file now shrinks down to 571 bytes. A quick investigation shows that unticking and reticking the box silently changes the PNG from a 48 color palette to a RGB/A image, which is smaller in the case of this small image.

If I use the new File > Generate Assets checkbox and name my layer “reddot.png” the automatically-saved PNG file in the PSD’s subfolder is the 608 byte version.

If I choose File > Export > Save for Web (Legacy) and choose to save a PNG-24 file:

image

… Photoshop reassures me that I’ve made good choices:

image

… But it’s lying. The information at the bottom left doesn’t account for the 935 bytes of useless metadata embedded in the image:

image

I need to change the Metadata dropdown to None:

image

…to get Adobe to omit most of the metadata, although it still wastes 37 bytes of your file advertising Adobe’s product. If you now distill the file, you can save those 37 bytes and pick up a 29 byte improvement in compression for a final file size of 411 bytes.image

So, as you can see, Adobe Photoshop can save this simple 477 byte image in sizes ranging from 477 bytes to a whopping 16723 bytes. The Adobe overhead isn’t “fixed”—it can be much larger: a 207K PNG file on Adobe’s website has 132K of metadata in it, while a 49.1K PNG file on Microsoft’s website contains 48.9K of Adobe metadata.

Lessons Learned:

  1. Learn how to use your tools.
  2. Expect your tools to lie to you.
  3. Use an optimizers.

-Eric

Photoshop and Save For Web

Optimize PNGs using PngDistill

Unfortunately, many PNG image generators opt for minimum compression time, failing to achieve maximum compression. Even worse, the most popular PNG generation tools often include huge amounts of unnecessary metadata that can bloat images by thousands of percent!

Fiddler now includes PngDistill, a simple tool that removes unnecessary metadata chunks and recompresses PNG image data streams using the Zopfli compression engine. Zopfli-based recompression often shaves 10% or more from the size of PNG files. You can access the PngDistill tool from the context menu of Fiddler’s ImageView inspector:

image

Automation

While it is well-integrated into Fiddler, PngDistill , which is installed to C:\program files (x86)\Fiddler2\Tools folder, only requires PngDistill.exe (a .NET application) and zopfli.exe to run; you can use these tools without using Fiddler.

To run PngDistill against an entire local folder of images, you can do so from the command prompt:

   for /f "delims=|" %f in ('dir /b *.png') do PngDistill "%f" replace

This script runs PngDistill on every image in the current folder, replacing any image for which the distillation process saved bytes. You can then update the images on your server with the optimized images.

Running PngDistill .exe without any arguments will show the usage instructions:

image

Notes

  • The “Minify-then-compress” Best Practice applies to PNGs. While large fields of empty pixels compress really well, the browser must decompress those fields back into memory. So, if you’re building a sprite image with all of your site’s icons, don’t leave a huge empty area in it.
  • More advanced optimizations for PNG files are available using filters, color depth reduction, etc. PngDistill does not undertake these optimizations as its goal is to be 100% safe for automation, with no possibility of a user-visible change in the pixels of the image.
  • PngDistill partially supports .ICO files. Icon files may contain embedded PNGs; when run on a .ICO, PngDistill will extract the PNGs and save them externally; you will need to rebuild the .ICO file with the new PNG file(s).

-Eric

Optimize PNGs using PngDistill