Note that there are some explanatory texts on larger screens.

plurals
  1. POWindows Forms: Making a cursor bitmap partially transparent
    primarykey
    data
    text
    <p>I want to use partially transparent images in drag/drop operations. This is all set up and works fine, but the actual transformation to transparency has a weird side effect. For some reason, the pixels seem to be blended against a black background. </p> <p>The following image describes the problem:</p> <p><img src="https://i.stack.imgur.com/AEPKZ.png" alt="Transparency problem"></p> <p>Figure a) is the original bitmap.</p> <p>Figure b) is what is produced after alpha blending has been performed. Obviously this is a lot darker than the intended 50% alpha filter intended.</p> <p>Figure c) is the desired effect, image a) with 50% transparency (added to the composition with a drawing program).</p> <p>The code I use to produce the trasparent image is the following:</p> <pre><code>Bitmap bmpNew = new Bitmap(bmpOriginal.Width, bmpOriginal.Height); Graphics g = Graphics.FromImage(bmpNew); // Making the bitmap 50% transparent: float[][] ptsArray ={ new float[] {1, 0, 0, 0, 0}, // Red new float[] {0, 1, 0, 0, 0}, // Green new float[] {0, 0, 1, 0, 0}, // Blue new float[] {0, 0, 0, 0.5f, 0}, // Alpha new float[] {0, 0, 0, 0, 1} // Brightness }; ColorMatrix clrMatrix = new ColorMatrix(ptsArray); ImageAttributes imgAttributes = new ImageAttributes(); imgAttributes.SetColorMatrix(clrMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); g.DrawImage(bmpOriginal, new Rectangle(0, 0, bmpOriginal.Width, bmpOriginal.Height), 0, 0, bmpOriginal.Width, bmpOriginal.Height, GraphicsUnit.Pixel, imgAttributes); Cursors.Default.Draw(g, new Rectangle(bmpOriginal.Width / 2 - 8, bmpOriginal.Height / 2 - 8, 32, 32)); g.Dispose(); imgAttributes.Dispose(); return bmpNew; </code></pre> <p>Does anyone know why the alpha blending does not work?</p> <p><strong>Update I:</strong></p> <p>For clarity, the code does work if I'm alphablending on top of a drawn surface. The problem is that I want to create a completely semitransparent image from an existing image and use this as a dynamic cursor during drag/drop operations. Even skipping the above and only painting a filled rectangle of color 88ffffff yields a dark grey color. Something fishy is going on with the icon.</p> <p><strong>Update II:</strong></p> <p>Since I've reseached a whole lot and believe this has got something to do with the Cursor creation, I'm gonna include that code below too. If I GetPixel-sample the bitmap just before the CreateIconIndirect call, the four color values seem to be intact. Thus I have a feeling the culprits might be the hbmColor or the hbmMask members of the IconInfo structure.</p> <p>Here's the IconInfo structure:</p> <pre><code>public struct IconInfo { // http://msdn.microsoft.com/en-us/library/ms648052(VS.85).aspx public bool fIcon; // Icon or cursor. True = Icon, False = Cursor public int xHotspot; public int yHotspot; public IntPtr hbmMask; // Specifies the icon bitmask bitmap. If this structure defines a black and white icon, // this bitmask is formatted so that the upper half is the icon AND bitmask and the lower // half is the icon XOR bitmask. Under this condition, the height should be an even multiple of two. // If this structure defines a color icon, this mask only defines the AND bitmask of the icon. public IntPtr hbmColor; // Handle to the icon color bitmap. This member can be optional if this structure defines a black // and white icon. The AND bitmask of hbmMask is applied with the SRCAND flag to the destination; // subsequently, the color bitmap is applied (using XOR) to the destination by using the SRCINVERT flag. } </code></pre> <p>And here is the code that actually creates the Cursor:</p> <pre><code> public static Cursor CreateCursor(Bitmap bmp, int xHotSpot, int yHotSpot) { IconInfo iconInfo = new IconInfo(); GetIconInfo(bmp.GetHicon(), ref iconInfo); iconInfo.hbmColor = (IntPtr)0; iconInfo.hbmMask = bmp.GetHbitmap(); iconInfo.xHotspot = xHotSpot; iconInfo.yHotspot = yHotSpot; iconInfo.fIcon = false; return new Cursor(CreateIconIndirect(ref iconInfo)); } </code></pre> <p>The two external functions are defined as follows:</p> <pre><code> [DllImport("user32.dll", EntryPoint = "CreateIconIndirect")] public static extern IntPtr CreateIconIndirect(ref IconInfo icon); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo); </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload