我真的需要一些帮助。我正在尝试将我认为具有预乘 alpha 的 32bpp 图像加载到MenuItem上(我按照本指南在 GIMP 中制作图像)。我知道 ContextMenuStrip 类并且不想使用它。
以下是我用来将图像设置到 MenuItem 上的代码:
// apis
[DllImport("user32.dll", SetLastError = true)]
static extern bool SetMenuItemInfo(IntPtr hMenu, uint uItem, bool fByPosition,
[In] ref MENUITEMINFO lpmii);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern IntPtr LoadImage(IntPtr hinst, string lpszName, uint uType,
int cxDesired, int cyDesired, uint fuLoad);
// structures
[StructLayout(LayoutKind.Sequential)]
struct MENUITEMINFO
{
public uint cbSize;
public uint fMask;
public uint fType;
public uint fState;
public uint wID;
public IntPtr hSubMenu;
public IntPtr hbmpChecked;
public IntPtr hbmpUnchecked;
public IntPtr dwItemData;
public string dwTypeData;
public uint cch;
public IntPtr hbmpItem;
}
// constants
private const uint LR_LOADFROMFILE = 0x10u;
private const uint IMAGE_BITMAP = 0x0u;
private const uint MIIM_BITMAP = 0x80u;
// points the to the image below in the preview of GIMP
private const string IMAGE_PATH = @"C:\Test\Images\premultalpha.bmp";
// methods
private void SetMenuItemImage()
{
// get the hbitmap for the image
// i am assuming that the alpha channel is preservered on this call
IntPtr hbitmap = LoadImage(IntPtr.Zero, IMAGE_PATH,
IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
// create the menuiteminfo structure
MENUITEMINFO mii = new MENUITEMINFO();
mii.cbSize = (uint)Marshal.SizeOf(typeof(MENUITEMINFO));
// retrieves or sets the hbmpItem member
mii.fMask = MIIM_BITMAP;
// handle to the bitmap displayed
mii.hbmpItem = hbitmap;
// returns true
SetMenuItemInfo(this.ContextMenu1.Handle, 0, true, ref mii);
}
这是使用我的图像的代码的结果:
这里明显的问题是没有透明度,而是有黑色背景。
这是在保存和重新打开之前按照指南制作预乘 Alpha 通道后图像在 GIMP 中的样子:
这是保存并重新打开后图像在 GIMP 中的样子:
我注意到我再也看不到图片之前版本上的 Alpha 通道蒙版。我不确定这是否与我尝试将之前的图片保存为 .bmp 时收到的这条消息有关:
抱歉,这篇文章太长了,但我正在尽力提供所有我能提供的信息。我不确定我的问题是关于 MenuItem 的透明度。有人告诉我,如果您加载具有 32bpp 和预乘 alpha 的位图,则透明度会正常工作。
我知道我不能使用托管方法Bitmap.Gethbitmap()
,因为它丢失了 alpha 通道。这就是为什么我改为使用LoadImage
winapi 调用以希望保留它。
任何帮助是极大的赞赏。