Skip to content

Comments

Ignore undefined all-zero alpha data for 32-bit icons without mask#2986

Merged
HeikoKlare merged 1 commit intoeclipse-platform:masterfrom
vi-eclipse:master-497
Jan 30, 2026
Merged

Ignore undefined all-zero alpha data for 32-bit icons without mask#2986
HeikoKlare merged 1 commit intoeclipse-platform:masterfrom
vi-eclipse:master-497

Conversation

@ShahzaibIbrahim
Copy link
Contributor

I have a png image (icon), which has no maskData and no alpha pixels (that means it is fully opaque):
image

On Windows, GetDIBits() may return undefined alpha bytes for 32-bit BI_RGB bitmaps, commonly resulting in all-zero alpha even for fully opaque images.

When icon mask data is missing, this caused opaque icons to be incorrectly treated as fully transparent.

Reject all-zero alpha data and only replace empty mask data when the alpha channel contains meaningful (non-opaque, non-zero) values.

How to test

  • Run the following snippet on 100% (only reproducible on 100%, otherwise image will be scaled, image semantics will change and we will never run into this issue):

Note: Add the attached image on the same folder as snippet

import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;

public class ImageTransparencyFix {
    public static void main(String[] args) {
    	System.setProperty("swt.autoScale.updateOnRuntime", "true");
        Display display = new Display();
        Shell shell = new Shell(display);
        shell.setText("Image Transparency Toolbar Demo");
        shell.setSize(300, 200);
        shell.setLayout(new FillLayout());

        Image original = new Image(display, ImageTransparencyFix.class.getResourceAsStream("png-image.png"));

        ImageData data = original.getImageData();
        Image transparentImage = new Image(display, data, data.getTransparencyMask());

        ToolBar imageToolBar = new ToolBar(shell, SWT.FLAT);
        for (int i = 0; i < 3; i++) {
            ToolItem item = new ToolItem(imageToolBar, SWT.PUSH);
            item.setImage(transparentImage);
            item.setToolTipText("Image ToolItem ToolTip " + i);
        }

        // 4) Open UI
        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) display.sleep();
        }

        // 5) Dispose resources
        transparentImage.dispose();
        original.dispose();
        display.dispose();
    }
}
  • You will see the images on toolbar will be completely transparent.
image

After fix

image

@ShahzaibIbrahim ShahzaibIbrahim marked this pull request as draft January 20, 2026 10:55
@ShahzaibIbrahim
Copy link
Contributor Author

ShahzaibIbrahim commented Jan 20, 2026

Drafted because I need suggestion here in the case where, what if the image was made completely transparent by choice? Meaning user define the image to be completely transparent (all 0 alpha pixels). Is this a viable/possible case here? Or that this fix is enough? as we can't know for sure if GetDIBits() is returning 0 as un-defined alpha-byte or was it really 0.

Documentation for GetDIBits -> https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-getdibits#return-value

@github-actions
Copy link
Contributor

github-actions bot commented Jan 20, 2026

Test Results (win32)

   34 files  ±0     34 suites  ±0   4m 32s ⏱️ - 1m 8s
4 640 tests ±0  4 567 ✅ ±0  73 💤 ±0  0 ❌ ±0 
  170 runs  ±0    167 ✅ ±0   3 💤 ±0  0 ❌ ±0 

Results for commit cc3b6e7. ± Comparison against base commit 7f413b7.

♻️ This comment has been updated with latest results.

@ShahzaibIbrahim ShahzaibIbrahim marked this pull request as ready for review January 22, 2026 09:41
@arunjose696
Copy link
Contributor

Changes look good to me. I have tested the snippet, and it fixes the problem mentioned in the issue. However, there are some CI failures, which I don’t think are related. @ShahzaibIbrahim, could you please rerun the CI?

@ShahzaibIbrahim ShahzaibIbrahim force-pushed the master-497 branch 2 times, most recently from 8ff599c to 5b8c337 Compare January 27, 2026 09:48
@ShahzaibIbrahim ShahzaibIbrahim deleted the master-497 branch January 30, 2026 14:51
Copy link
Contributor

@HeikoKlare HeikoKlare left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out that OS.GetDIBits does not guarantee to return alpha data when not having mask data and requesting for 32 bits. Taken a look at all the documentations and asking Copilot, there does not seem to be a proper way to retrieve an alpha-aware image in this way (i.e., with this DPI) at all. It might be that all this special case handling for alpha data could just be removed, but since the original issue that was solved with this can currently not be reproduced, there is no chance to see if we can fix it in any other way and that removing this code that not produce any regression. On the other hand, assuming that empty alpha data is invalid (as the image would be completely transparent otherwise), seems reasonable. Thus I am in favor of merging this.

@HeikoKlare HeikoKlare restored the master-497 branch January 30, 2026 15:00
@HeikoKlare HeikoKlare reopened this Jan 30, 2026
On Windows, GetDIBits() may return undefined alpha bytes for 32-bit
BI_RGB bitmaps, commonly resulting in all-zero alpha even for fully
opaque images.

When icon mask data is missing, this caused opaque icons to be
incorrectly treated as fully transparent.

Reject all-zero alpha data and only replace empty mask data when the
alpha channel contains meaningful (non-opaque, non-zero) values.
@HeikoKlare HeikoKlare merged commit 6576cab into eclipse-platform:master Jan 30, 2026
17 checks passed
@HeikoKlare HeikoKlare deleted the master-497 branch January 30, 2026 15:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Discuss Images with no image transparency

3 participants