Skip to content

image/png: Encode is not as efficient as zlib-based encoders #16196

@olt

Description

@olt

Paletted PNGs like this map tile (http://a.tile.openstreetmap.org/13/4404/2688.png) will increase by 20-30% in size when encoded with image/png.Encode.
See https://gist.github.com/olt/022a206444f20c147c4bc9a54fd1a433 for example re-encoder.

The size does not change much when I re-encode the image with Image Magick (convert) or Python Image Library (PIL/Pillow):

% curl': curl "http://a.tile.openstreetmap.org/13/4404/2688.png" -o orig.png
% convert orig.png image-magick.png
% python -c 'from PIL import Image; Image.open("orig.png").save("pil.png")'
% go run convert.go
% ls -l *.png
-rw-r--r--  1 olt  staff  44099 Jun 27 15:25 go.png
-rw-r--r--  1 olt  staff  34583 Jun 27 15:21 image-magick.png
-rw-r--r--  1 olt  staff  34491 Jun 27 15:21 orig.png
-rw-r--r--  1 olt  staff  34521 Jun 27 15:22 pil.png

Changing the compression level in Go does not make any huge difference.

zlib allows to set different compress strategies. One of the strategies is Z_FILTERED, which is optimized for filtered data as found in PNGs.

From http://www.zlib.net/manual.html:

The strategy parameter is used to tune the compression algorithm. Use the value ... Z_FILTERED for data produced by a filter (or predictor),...
The effect of Z_FILTERED is to force more Huffman coding and less string matching; it is somewhat intermediate between Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY.

PIL allows to select the strategy and it gives file sizes in the range of 34521 to 45117:

% python -c 'from PIL import Image; Image.open("orig.png").save("pil.png", compress_type=Image.HUFFMAN_ONLY)'

Implementing a Z_FILTERED-like strategy should give much smaller files and it should have more impact than #15622.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions