简体   繁体   English

WIC“复制像素”调用后预乘像素

[英]Pre-multiply pixels after WIC 'Copy Pixels' call

I have been looking at creating PARGB32 bitmaps. 我一直在寻找创建PARGB32位图。 This seems to be necessary to produce images which work fully with post-XP menu-items. 要生成与XP后菜单项完全兼容的图像,这似乎是必需的。

This example http://msdn.microsoft.com/en-us/library/bb757020.aspx?s=6 is very interesting but rather complicated as I have rarely if ever used OLE interfaces before. 此示例http://msdn.microsoft.com/zh-cn/library/bb757020.aspx?s=6非常有趣,但非常复杂,因为我以前很少使用过OLE接口。 However, after carefully studying the piece of code that uses WIC and OLE I think I understand how it works. 但是,在仔细研究了使用WIC和OLE的代码段之后,我想我知道它是如何工作的。 The one thing which confuses me is the comment by user 'David Hellerman'. 让我感到困惑的一件事是用户“ David Hellerman”的评论。 To summarize, he states this example function is not complete. 总而言之,他指出此示例功能尚未完成。 It does not take in to account any potential alpha information in the source Icon - and if there IS alpha data it must be pre-multiplied on a pixel by pixel basis while scanning through the ppvBuffer variable. 它不考虑源图标中的任何潜在alpha信息-如果存在alpha数据,则在扫描ppvBuffer变量时必须逐个像素对其进行预乘。

My question has two parts. 我的问题分为两个部分。 How do I detect the presence of alpha data in my icons while using WIC instead of GDI and how do I go about pre-multiplying it in to the pixels if it does exist? 当使用WIC而不是GDI时,如何检测图标中的alpha数据;如果存在,如何将其预乘到像素中?

Technically, the sample code is wrong because it does not account for or check the format of the IWICBitmap object when calling CopyPixels. 从技术上讲,该示例代码是错误的,因为在调用CopyPixels时,该示例代码无法说明或检查IWICBitmap对象的格式。 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. 创建位图时,CreateBitmapFromHICON可能始终使用特定格式(该示例表明它是32位PBGRA,但注释表明它是BGRA),但MSDN并未对此进行记录,并且依赖它至少是一种不好的形式。 WIC supports many pixel formats, and not all of them are 32-bit or RGB. WIC支持许多像素格式,但并非所有像素格式都是32位或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). 您可以使用WICConvertBitmapSource函数( http://msdn.microsoft.com/zh-cn/library/windows/desktop/ee719819(v=vs.85).aspx )将数据转换为特定的已知格式,在这种情况下,您将需要GUID_WICPixelFormat32bppPBGRA(您可能已经习惯于将这种格式写为PARGB,但是WIC根据字节数组而不是32位int的成分顺序使用了一种奇怪的命名约定)。 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. 您可以以与MSDN示例使用其IWICBitmap相同的方式使用生成的IWICBitmapSource。

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. 您可以使用IWICBitmapSource :: GetPixelFormat( http://msdn.microsoft.com/en-us/library/windows/desktop/ee690181 (v=vs.85) .aspx )确定图像的像素格式。 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. 但是,通常无法知道alpha数据(如果格式包含alpha数据)是否已预乘,您只需要识别格式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. 当我想专门处理多种格式时,通常会使用GetPixelFormat,但对于我不处理的格式,我仍然会使用WICConvertBitmapSource。

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. 无法基于IWICBitmap来检测该图标最初是否具有Alpha通道,因为在所有情况下WIC都会从该图标创建一个具有Alpha通道的位图。 It's also not necessary, because premultiplying the alpha is a no-op in this case. 这也是不必要的,因为在这种情况下,将Alpha乘以是无操作的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM