我想在拖放操作中使用部分透明的图像。这一切都设置好了,工作正常,但实际转换为透明度有一个奇怪的副作用。出于某种原因,像素似乎与黑色背景混合。
下图描述了该问题:
图 a) 是原始位图。
图 b) 是执行 alpha 混合后产生的结果。显然,这比预期的 50% alpha 滤镜要暗得多。
图 c) 是所需的效果,图像 a) 具有 50% 的透明度(使用绘图程序添加到合成中)。
我用来生成透明图像的代码如下:
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;
有谁知道为什么 alpha 混合不起作用?
更新一:
为清楚起见,如果我在绘制的表面上进行字母混合,则代码确实有效。问题是我想从现有图像创建一个完全半透明的图像,并在拖放操作期间将其用作动态光标。即使跳过上面的内容,只绘制一个填充颜色为 88ffffff 的矩形,也会产生深灰色。图标有些可疑。
更新二:
由于我已经研究了很多并相信这与 Cursor 的创建有关,所以我也将在下面包含该代码。如果我在调用 CreateIconIndirect 之前对位图进行 GetPixel 采样,则四个颜色值似乎完好无损。因此,我感觉罪魁祸首可能是 IconInfo 结构的 hbmColor 或 hbmMask 成员。
这是 IconInfo 结构:
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.
}
这是实际创建光标的代码:
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));
}
两个外部函数定义如下:
[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);