How do I embed multiple sizes in an .ico file?

ImageMagick (Windows/Mac/Linux) contains a command-line tool called convert that can be used for many things, including packing multiple images in one icon:

convert 16.png 32.png 48.png 128.png 256.png -colors 256 icon.ico

The previous command takes 5 PNG images, and combines them into a single .ico file.

Unlike the other answers, this method can easily be used in batch scripts to automatically generate several icon files. In one of my projects, I have a single vector image (SVG), and use Inkscape to generate png's of various sizes, followed by convert to create a icon container. This is a reduced example (in a bash script):

#!/bin/bash
for size in 16 32 48 128 256; do
    inkscape -z -e $size.png -w $size -h $size icon.svg >/dev/null 2>/dev/null
done
convert 16.png 32.png 48.png 128.png 256.png -colors 256 icon.ico

Better command for ImageMagick:

convert in.jpg -define icon:auto-resize=16,48,256 -compress zip out.ico

You can do this for free in GIMP. There are brief instructions for doing this here.

To quote:

  1. Open your image in Gimp
  2. Make your canvas square
  3. Resize your layer to the image
  4. Scale the layer to the largest size in your .ico file like 64 pixels
  5. Duplicate the layer
  6. Scale the duplicate layer to the next size
  7. Keep duplicating / scaling for all the sizes you want in your .ico file
  8. Save as .ico

In your case, you could either start with the largest image and scale down for each duplicated image, or you could just add new layers and import the specific icon images you wanted into that layer.


Here’s the accepted answer by Rob W, with a trivial adaptation to avoid having to type the sizes (16, 32, etc.) more than once:

#!/bin/bash
files=()
for size in 16 32 48 128 256; do
    inkscape -z -e "$size.png" -w "$size" -h "$size" logo.svg > /dev/null 2> /dev/null
    files+=("$size.png")
done
convert "${files[@]}" -colors 256 favicon.ico
unlink  "${files[@]}"

Here logo.svg represents the input (source) image, from which we create smaller files of the desired sizes (16.png, 32.png, etc.) which we then combine into the output (result) icon file, favicon.ico.  You can change the list of sizes in line 3, e.g., to "16 24 32 48 64 72 128", and the convert command will automatically adapt accordingly, because this script uses the technique described by G-Man in his answer here to build an array of filenames.  And finally we unlink (remove) the PNG files created in line 4, using the array of filenames again.


I’ve noticed that the command:

convert logo.svg -define icon:auto-resize=16,48,256 -compress zip favicon.ico

(equivalent to the one presented in user400747’s answer) actually scaled bitmap image (lost quality) and layers background lost transparency.


You might try Matthias Benkmann's png2ico. It is free and can pack multi size png's into a single ico file.