↗ SVGtopixGuides

Why does my PNG to ICO conversion have a white background?

In our tests, the white background came from the source image, not the converter: the site owner's manual Chrome exports and a separate local reproduction both retained transparent corners until the source was flattened onto white.

Start by checking the source PNG's corner alpha, then check the same corners in the exported ICO. A white-looking preview alone does not establish that white pixels were saved.

Use the PNG to ICO converter to repeat the test with the source files below.

Three sources, two conversion environments

We used an opaque green image, a transparent circle, and that same circle flattened onto white. The site owner manually converted the sources in Chrome and supplied the downloaded ICO files. Those browser exports were not automated by us.

The local reproduction ran the downloaded SVGtopix conversion module with a Node canvas adapter. It used a different rendering environment. We kept its outputs separate from the manual browser exports.

Both sets were decoded with the same ICO inspection script. The script read each directory entry, extracted its PNG payload and recorded the pixels.

The sample labels in the tables are:

The corners separate transparency from painted white

Every value below was decoded from the saved files. Each of the seven frames—16, 24, 32, 48, 64, 128 and 256px—returned the same corner values shown for its sample. The manual site exports and local reproduction matched at all four corners.

SampleTop-left RGBATop-right RGBABottom-left RGBABottom-right RGBA
G[24,77,65,255][24,77,65,255][24,77,65,255][24,77,65,255]
T[0,0,0,0][0,0,0,0][0,0,0,0][0,0,0,0]
W[255,255,255,255][255,255,255,255][255,255,255,255][255,255,255,255]

The transparent circle retained alpha 0 at every corner. Flattening that source onto white changed the corner result to opaque white: alpha 255, with all three color channels at 255.

The green control stayed opaque green at its corners. These controls did not show the converter adding a white background to the transparent source.

That finding applies to these saved sources and exports. It does not identify the cause of an untested file's background.

Matching corners did not mean matching files

The complete comparison is below. All numbers come from the saved ICOs and decoded pixels. Differences are manual site export minus local reproduction. Offsets and payload lengths are in bytes.

SampleFrame (px)Offset: local → siteOffset differencePayload: local → siteByte differenceDifferent RGBA pixelsDifferent alpha pixels
G16118→1180115→122+700
G24233→240+7125→137+1200
G32358→377+19139→136-300
G48497→513+16172→240+6800
G64669→753+84240→283+4300
G128909→1036+127424→872+44800
G2561333→1908+575888→2377+148900
T16118→1180325→375+5000
T24443→493+50597→603+6132118
T321040→1096+56684→805+12100
T481724→1901+1771273→1464+191369269
T642997→3365+3681745→2208+46300
T1284742→5573+8315567→7072+150526682460
T25610309→12645+233616930→22560+5630107969292
W16118→1180374→405+3100
W24492→523+31632→647+151180
W321124→1170+46724→867+14300
W481848→2037+1891370→1495+1253790
W643218→3532+3141568→2158+59000
W1284786→5690+9045807→6791+98427880
W25610593→12481+188815318→21028+5710105440

The green control had identical decoded pixels at every size, despite different payload lengths. A byte difference alone therefore did not establish a pixel difference.

Both circle samples had pixel differences at 24, 48, 128 and 256px. The transparent circle also had alpha differences at those sizes. We cannot describe all those differences as RGB changes beneath fully transparent pixels.

The RGBA comparison includes stored RGB beneath transparent pixels. Those counts are not a visual white-fringe test. They do not, by themselves, establish a visible white edge.

For a separate controlled comparison of invisible source colors, see semi-transparent PNG pixels in ICO frames.

What to check in your own file

If the source already contains opaque white corners, removing the background must happen before conversion. Our flattened source carried that white into both sets of outputs.

If the source corners have alpha 0, inspect the exported frame's alpha too. In this test, transparent source corners remained transparent in the manual site exports. Do not infer saved pixel values from the preview's background color.

If the corners remain transparent but the edge still looks wrong, inspect the edge separately. Our corner agreement coexisted with other pixel differences. A corner check cannot certify the whole outline.

For vector input rather than a PNG source, use the separate SVG to ICO frame inspection. Its source artwork and measurements are different.

Reproduce it yourself

  1. Download the complete evidence package, choose each supplied source PNG in the linked converter, keep all seven sizes selected and save each ICO.
  2. Run python -m pip install pillow, then run python compare-manual.py from the extracted package to inspect the included manual exports and local outputs.
  3. Read comparison-manual/comparison.json and the per-frame difference CSVs; compare all four corner values and the decoded pixels before drawing a conclusion from file size or a preview.