Search code examples
bashpngpagespeed

Batch Optimize PNG for google pagespeed


From: http://gtmetrix.com/reports/hosting.site.dev.nexwrx.com/OUsrZOCY _include/img/menu-mobile.png could save 1.0KiB (82% reduction)

things I have tried

pngcrush _include/img/menu-mobile.png menu-mobile.png

Best pngcrush method = 6 (ws 12 fm 5 zl 9 zs 0) = 215 for menu-mobile.pn (1.38% critical chunk reduction) (0.24% filesize reduction)

when I try optipng -o7 _include/img/menu-mobile.png _include/img/menu-mobile.png is already optimized

pngquant --quality=75-80 _include/img/logo

pngpngquant: mempool.c:40: mempool_create: Assertion `!((uintptr_t)(*mptr + (*mptr)->used) & 15UL)' failed. Aborted

pngquant just seems to fail on everything (ubuntu 14.04) version 2.01

Any idea how I can get 82% reduction as google states on a .png?


Solution

  • Google removed the iTXt and tEXt chunks, saving around 1050 bytes, and reduced the pixels from 32-bits/pixel RGBA to 4-bits/pixel indexed, saving a few more bytes:

    $ pngcheck -v menu-mobile.png
    File: menu-mobile.png (1265 bytes)
      chunk IHDR at offset 0x0000c, length 13
        16 x 32 image, 32-bit RGB+alpha, non-interlaced
      chunk iTXt at offset 0x00025, length 1001, keyword: XML:com.adobe.xmp
        uncompressed, no language tag
        no translated keyword, 980 bytes of UTF-8 text
      chunk tEXt at offset 0x0041a, length 25, keyword: Software
      chunk IDAT at offset 0x0043f, length 158
        zlib: deflated, 4K window, maximum compression
      chunk IEND at offset 0x004e9, length 0
    No errors detected in menu-mobile.png (5 chunks, 38.2% compression).
    
    $ pngcheck -v menu-mobile-opt.png
    File: menu-mobile_opt.png (216 bytes)
      chunk IHDR at offset 0x0000c, length 13
        16 x 32 image, 4-bit palette, non-interlaced
      chunk PLTE at offset 0x00025, length 36: 12 palette entries
      chunk tRNS at offset 0x00055, length 11: 11 transparency entries
      chunk IDAT at offset 0x0006c, length 88
        zlib: deflated, 512-byte window, default compression
      chunk IEND at offset 0x000d0, length 0
    No errors detected in menu-mobile_opt.png (5 chunks, 15.6% compression).
    

    Pngcrush can do a little better by reducing the pixels to 16-bits/pixel Gray-alpha:

    $ pngcrush -s -reduce -rem text menu-mobile.png menu-mobile-pc.png
    $ pngcheck -v menu-mobile-pc.png
    File: menu-mobile-pc.png (175 bytes)
      chunk IHDR at offset 0x0000c, length 13
        16 x 32 image, 16-bit grayscale+alpha, non-interlaced
      chunk IDAT at offset 0x00025, length 118
        zlib: deflated, 2K window, maximum compression
      chunk IEND at offset 0x000a7, length 0
    No errors detected in menu-mobile-pc.png (3 chunks, 82.9% compression).
    

    In this case, the IDAT chunk that contains the compressed pixel data is 30 bytes larger than google's result, but that's offset by the fact that the Gray-alpha color type doesn't require the PLTE (36 bytes of data plus 12 bytes of chunk overhead) and the tRNS (11 bytes data + 12 bytes overhead) chunks. For images with larger dimensions, this tradeoff would probably be different.