How to compress ico file on imagemagick or other

Viewed 1270

I created a 32x32 png in photoshop exported as 500bytes.

favicon

Converted to ico using

magick convert .\favicon.png favicon.ico

And it became 5kb.
Question? Is there there a compression flag in imagemagick or anoter way to compress favicon.ico?

1 Answers

I just tried @dan-mašek's suggestion and it definitely works better than ImageMagick.

With the PNGs I was working with, ImageMagick gave me a 5.4K .ico file despite asking for it to use .ico's support for embedded PNGs for the compression (apparently it ignores you for sizes under 256x256) while Pillow got it down to 1.8K.

Here's how I went about crunching down my favicons based on an existing PNG-optimizing shell script I cooked up years ago:

#!/bin/sh

optimize_png() {
    for X in "$@"; do
        echo "---- Using pngcrush to strip irrelevant chunks from $X ----"
        # Because I don't know if OptiPNG considers them all "metadata"
        pngcrush -ow -q -rem alla -rem cHRM -rem gAMA -rem iCCP -rem sRGB \
            -rem time "$X" | egrep -v '^[ \|]\|'
    done

    echo "---- Using OptiPNG to optimize delta filters ----"
    # ...and strip all "metadata"
    optipng -clobber -o7 -zm1-9 -strip all -- "$@" 2>&1 | grep -v "IDAT size ="

    echo "---- Using AdvanceCOMP to zopfli-optimize DEFLATE ----"
    advpng -z4 "$@"
}

optimize_png 16.png 32.png

python3 << EOF
from PIL import Image

i16 = Image.open('16.png')
i32 = Image.open('32.png')
i32.save('src/favicon.ico', sizes=[(16, 16), (32, 32)], append_images=[i16])
EOF

Just be aware that:

  1. pngcrush and advpng don't take -- as arguments, so you have to prefix ./ onto relative paths which might start with -.
  2. .save in PIL must be called on the largest image so, if you have a dynamic list of images, you probably want something like this:
images.sort(key=lambda x: x.size)
images[-1].save('favicon.ico', sizes=[x.size for x in images], append_images=images)
Related