Я хочу использовать частично прозрачные изображения в операциях перетаскивания. Все это настроено и работает нормально, но фактическое преобразование в прозрачность имеет странный побочный эффект. Почему-то пиксели выглядят смешанными на черном фоне.
Следующая картинка описывает проблему:
Рисунок а) - исходное растровое изображение.
Рисунок б) - это то, что получается после альфа-смешивания. Очевидно, что это намного темнее, чем предполагаемый 50% -ный альфа-фильтр.
Рисунок c) - желаемый эффект, изображение а) с прозрачностью 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;
Кто-нибудь знает, почему не работает альфа-смешивание?
Обновление I:
Для ясности, код работает, если я могу выполнить альфа-заливку поверх нарисованной поверхности. Проблема в том, что я хочу создать полностью полупрозрачное изображение из существующего изображения и использовать его в качестве динамического курсора во время операций перетаскивания. Даже если пропустить вышеупомянутое и только нарисовать закрашенный прямоугольник цвета 88ffffff, получится темно-серый цвет. Что-то подозрительное происходит со значком.
Обновление II:
Так как я много переписал и считаю, что это как-то связано с созданием Курсора, я также включу этот код ниже. Если я получу GetPixel-образец растрового изображения непосредственно перед вызовом CreateIconIndirect, четыре значения цвета окажутся неповрежденными. Таким образом, я чувствую, что виновными могут быть члены hbmColor или hbmMask структуры IconInfo.
Вот структура 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);