← All Tools

Inside an ICO File, the Icons Are Actually All Stored as PNG

Guide · Last verified Aug 27, 2026

If you've ever opened an ICO file while making a favicon, you already know it packs several sizes — everything from 16×16 up to 256×256 — into one file. What's less well known is exactly what format the images inside are stored in. The short answer: most ICO files made today store their image data as raw PNG bytes. This guide walks through the ICO format's structure and why PNG became the standard inside it, based on the actual code that runs in the ICO Converter.

1. ICO Isn't an Image Format — It's a "Container" Format

PNG and JPG each encode a single image, but ICO was designed for a different purpose entirely. A single ICO file starts with a header called ICONDIR, followed by a series of ICONDIRENTRY records (one per resolution), with the actual image bytes appended in sequence toward the end of the file. In other words, ICO is a container that bundles "a 16×16 image, a 32×32 image, a 256×256 image" and so on into one file, letting the operating system pick whichever size fits the situation. As for how each individual image inside that container is actually encoded, the ICO spec allows two options: uncompressed BMP (DIB) bitmaps, or PNG.

2. The Legacy Approach: Uncompressed BMP's File Size Problem

Traditional ICO files stored each resolution's image as BMP (DIB, Device Independent Bitmap). BMP just lists pixel color values one after another with no compression, which made it simple to implement and reliably compatible with older systems — but it comes with a serious downside: file size balloons as the image gets larger. Storing a large icon like the 256×256 size introduced in Windows Vista as BMP alone can push a single entry to several hundred KB, which is wildly inefficient.

3. Since Windows Vista: Embedding Raw PNG Bytes

To solve this, starting with Windows Vista (2007), embedding PNG-compressed image bytes directly inside an ICONDIRENTRY — instead of BMP — became the standard. The ICO header structure itself didn't change at all; only what kind of "image data" sits inside it switched from BMP to PNG. When an operating system or browser reads an ICONDIRENTRY, it checks whether the data's first bytes match the PNG signature (\x89PNG) or a BMP header, and decodes it accordingly. The result is a much smaller file at the same visual quality — and the compression advantage is even more pronounced for icons and logos with large flat-color areas.

4. How the modoohub ICO Converter Actually Builds the File

Checking the ICO Converter's code directly confirms that it uses PNG compression for every selected size without exception — including small ones like 16×16. Here's how the conversion works:

  1. If the source image isn't square, the drawSize() function center-crops it into a square using the length of the shorter side.
  2. It resizes to each target size and gets the PNG bytes via canvas.toDataURL('image/png').
  3. The buildIco() function assembles the ICONDIR header and each size's ICONDIRENTRY byte-by-byte, then appends the PNG bytes obtained above.

One interesting detail is how the size field is handled. The width/height fields in an ICONDIRENTRY are single-byte fields, so they can only represent values from 0 to 255 — and the ICO spec has a special rule for when the size is 256: store a 0 in that field instead. The code follows this rule exactly, with sz===256?0:sz. Getting even this kind of low-level detail spec-compliant is what keeps the resulting ICO from breaking in either Windows or a browser.

5. The Size Difference Between BMP and PNG, in Real Numbers

Even just looking at the 256×256 size alone, the gap between the two approaches is stark. A 32-bit uncompressed BMP stores 4 bytes per pixel with no compression, so the math is simple.

MethodSize for one 256×256 entry (approx.)Notes
32-bit BMP (uncompressed)~264KB (256×256×4 bytes of color + AND mask)Size grows directly proportional to pixel count
PNG (compressed)A few KB to a few dozen KB (varies by image content)Gets smaller with more flat-color or transparent area

For small icon sizes like 16×16, 32×32, or 48×48, storing as BMP doesn't cost you much — but the moment a larger resolution like 128×128 or 256×256 is included, PNG's size advantage over BMP becomes obvious. Since ICO files are meant to bundle multiple resolutions together, a single large entry can easily dominate the whole file's size.

6. Is Compatibility Something to Worry About?

Every operating system released since Windows Vista, and every major browser in current use, reads PNG-compressed ICO entries without issue. For favicon purposes, there's effectively nothing to worry about. If your source is a PNG with an alpha channel (transparent background), that transparency carries through as well, so you can pair this with the Favicon Generator when turning a logo with a transparent background into a favicon.

Frequently Asked Questions

Q. If everything inside an ICO is PNG, can I just rename the extension to .png?

A. No. An ICO file is a container wrapped in an ICONDIR header and several ICONDIRENTRY structures — the PNG bytes are only included as a piece of that whole. Just renaming the extension doesn't turn it into a valid PNG file. If you want to use one of the individual images as a standalone PNG, you'll need to extract it separately or use an image conversion tool.

Q. Do all ICO converters use the PNG approach?

A. No, it varies by tool. Older utilities or legacy code sometimes still encode using BMP (DIB). modoohub's ICO Converter is implemented to use PNG compression for every selected size, with no exceptions.

Q. What happens if my source image isn't square?

A. The converter's drawSize() function center-crops the image into a square using the shorter side's length, then resizes it to the target size. If your subject isn't centered in the image, part of it can get cut off during that crop — for predictable results, it's safer to crop the image to a square yourself before uploading.

Q. Do I need to include the 256×256 size?

A. For a website favicon, 16×16, 32×32, and 48×48 are usually enough on their own. Include 256×256 when you need a larger icon, like for a Windows shortcut icon — keep in mind each additional size adds to the total file size.