简体   繁体   中英

Pre-multiply pixels after WIC 'Copy Pixels' call

I have been looking at creating PARGB32 bitmaps. This seems to be necessary to produce images which work fully with post-XP menu-items.

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. However, after carefully studying the piece of code that uses WIC and OLE I think I understand how it works. The one thing which confuses me is the comment by user '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.

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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