Windows Forms: частичная прозрачность растрового изображения курсора

Я хочу использовать частично прозрачные изображения в операциях перетаскивания. Все это настроено и работает нормально, но фактическое преобразование в прозрачность имеет странный побочный эффект. Почему-то пиксели выглядят смешанными на черном фоне.

Следующее изображение описывает проблему:

Transparency problem

Рисунок а) является исходным растровым изображением.

Рисунок б) - это то, что получается после альфа-смешивания. Очевидно, что это намного темнее, чем предполагаемый 50% -ный альфа-фильтр.

Рисунок 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;

Кто-нибудь знает, почему не работает альфа-смешение?

Update I:

Для ясности код действительно работает, если я делаю альфа-макет поверх нарисованной поверхности. Проблема в том, что я хочу создать полностью полупрозрачное изображение из существующего изображения и использовать его в качестве динамического курсора во время операций перетаскивания. Даже если пропустить вышеупомянутое и только нарисовать закрашенный прямоугольник цвета 88ffffff, получается темно-серый цвет. Что-то подозрительное происходит со значком.

Update 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);

Ответы на вопрос(5)

Ваш ответ на вопрос