1

我一直在研究创建 PARGB32 位图。这似乎是生成完全适用于 XP 后菜单项的图像所必需的。

这个示例 http://msdn.microsoft.com/en-us/library/bb757020.aspx?s=6 非常有趣但相当复杂,因为我以前很少使用 OLE 接口。但是,在仔细研究了使用 WIC 和 OLE 的代码之后,我想我理解它是如何工作的。让我感到困惑的一件事是用户“David Hellerman”的评论。总而言之,他指出此示例功能不完整。它不考虑源图标中的任何潜在 alpha 信息 - 如果存在 alpha 数据,则必须在扫描 ppvBuffer 变量时逐个像素地对其进行预乘。

我的问题有两个部分。如何在使用 WIC 而不是 GDI 时检测图标中是否存在 alpha 数据,如果确实存在,如何将其预乘到像素中?

4

1 回答 1

2

Technically, the sample code is wrong because it does not account for or check the format of the IWICBitmap object when calling CopyPixels. CreateBitmapFromHICON presumably always uses a specific format (that sample suggests it's 32-bit PBGRA but the comments are suggesting it's BGRA) when creating the bitmap, but that is not documented by MSDN, and relying on it is at the very least bad form. WIC supports many pixel formats, and not all of them are 32-bit or RGB.

You can use the WICConvertBitmapSource function (http://msdn.microsoft.com/en-us/library/windows/desktop/ee719819(v=vs.85).aspx) to convert the data to a specific, known format, in your case you'll want GUID_WICPixelFormat32bppPBGRA (you're probably used to seeing that format written as PARGB, but WIC uses an oddly sensible naming convention based on the order of components in an array of bytes rather than 32-bit ints). If converting means premultiplying the data, it will do that, but the point is that if you want a specific format you don't need to worry about how it gets there. You can use the resulting IWICBitmapSource in the same way that the MSDN sample uses its IWICBitmap.

You can use IWICBitmapSource::GetPixelFormat (http://msdn.microsoft.com/en-us/library/windows/desktop/ee690181(v=vs.85).aspx) to determine the pixel format of the image. However, there is no way to know in general whether the alpha data (if the format has alpha data) is premultiplied, you'd simply have to recognize the format GUID. I generally use GetPixelFormat when I want to handle more than one format specifically, but I still fall back on WICConvertBitmapSource for the formats I don't handle.

Edit: I missed part of your question. It's not possible to detect based on the IWICBitmap whether the icon originally had an alpha channel, because WIC creates a bitmap with an alpha channel from the icon in all cases. It's also not necessary, because premultiplying the alpha is a no-op in this case.

于 2014-12-02T01:26:16.747 回答