GNOME Bugzilla – Bug 755200
ICO exporter: Windows displays glitchy black pixels in 32-bit alpha images exported by GIMP
Last modified: 2015-09-19 00:39:20 UTC
Created attachment 311595 [details] Sample image to export as .ico. TL;DR: There is a bug in certain parts of Windows rendering ICOs with 32-bit images (with partial transparency). The ICOs exported by GIMP trigger this bug due to the way GIMP generates the AND mask. I think this is a bug in Windows, not GIMP, but there is an easy fix to the exporter that makes the problem go away. The code was rarely triggered on older versions of Windows, but on Windows 10, the bug affects taskbar icon rendering, making it much more severe. Steps to reproduce: 1. Open the attached file alphagradient.png. (This is a 32x32 image with a gradient from transparent to opaque blue.) 2. Export as alphagradient.ico. Ensure that you choose to export as "32 bpp, 8-bit alpha, no palette". 3. In Windows, right-click alphagradient.ico -> Properties. Expected: Gradient from transparent to 100% blue. Actual: Gradient from transparent to 50% black, then from 50% blue to 100% blue. (I will attach screenshots in follow-up comments.) (I tested on Windows 7 and 10; this probably goes way back though.) For bonus points, on Windows 10, set it as the icon to a shortcut and pin the shortcut to the taskbar. Note the bug manifests there also. Explanation: In the ICO file format, 32-bit images have both a 1-bit mask and an 8-bit alpha channel. Generally, Windows ignores the 1-bit mask and just gets its transparency information from the 8-bit alpha channel. But in *certain places* in Windows, it uses a different algorithm, equivalent to this: For each pixel with color (r, g, b, a) and mask bit m: If m (transparent mask): Composite with (0, 0, 0, a) Else (opaque mask): Composite with (r, g, b, a) So basically: - If your mask is transparent and alpha == 0, the pixel is fully transparent (good). - If your mask is transparent and alpha > 0, the pixel is BLACK (bad). - If your mask is opaque, the pixel is rendered correctly (good). Now GIMP's ICO exporter sets the mask to 1 (transparent) whenever alpha <50% (which is good for when the exported image does not have an alpha channel). This means that any pixels with <50% alpha will become black when viewed in certain places in Windows. The correct behaviour is to set the mask to 0 (opaque) whenever alpha > 0. Only set the mask to 1 (transparent) when alpha == 0. (Aside: I ran into this because I used GIMP to update the Chrome icon on Windows; see https://code.google.com/p/chromium/issues/detail?id=526622#c35) I will follow up with screenshots of the bug and a patch to fix GIMP's exporter.
Created attachment 311596 [details] The file currently generated by GIMP from this image.
Created attachment 311597 [details] The file generated by GIMP after my patch.
Created attachment 311598 [details] Screenshot of Windows properties dialog on alphagradient-before.ico
Created attachment 311599 [details] Screenshot of Windows properties dialog on alphagradient-after.ico
Created attachment 311600 [details] Screenshot of Windows 10 taskbar (before and after)
Created attachment 311601 [details] [review] Patch to fix ICO exporter. I've attached a number of screenshots showing how Windows renders the icon (before and after my patch). Also attached the patch.
Thanks, you win the prize for the best bug report, including patch, of the month :) Pushed to master and gimp-2-8: commit 32e8a4e116b6706b4199a948d19631342d27d9d8 Author: Matt Giuca <mgiuca@chromium.org> Date: Fri Sep 18 18:58:12 2015 +0200 plug-ins: Fix generation of the AND mask for 32-bit ICO images Previously, the mask would be transparent if the alpha was <50%. However, this causes pixels to become black in some places in Windows (notably, the taskbar on Windows 10). Therefore, always set the mask to opaque if a pixel is partially or fully opaque. (cherry picked from commit 07dfe4a5ebcf59ccf70a0775e406990aa1776dcb) plug-ins/file-ico/ico-save.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
Great! Thanks for the quick turnaround time, Michael.