使用GDI +绘制PixelFormat32bppPARGB图像使用传统的公式而不是预乘的公式

这里是一些最小的代码来显示一个问题:

static const int MAX_WIDTH = 320; static const int MAX_HEIGHT = 320; Gdiplus::Bitmap foregroundImg(MAX_WIDTH,MAX_HEIGHT,PixelFormat32bppPARGB); { Gdiplus::Graphics g(&foregroundImg); g.Clear(Gdiplus::Color(10,255,255,255)); } Gdiplus::Bitmap softwareBitmap(MAX_WIDTH,MAX_HEIGHT,PixelFormat32bppPARGB); Gdiplus::Graphics g(&softwareBitmap); g.SetCompositingMode(Gdiplus::CompositingModeSourceOver); g.SetCompositingQuality(Gdiplus::CompositingQualityDefault); g.Clear(Gdiplus::Color(255,0,0,0)); g.DrawImage(foregroundImg,0,0); CLSID encoder; GetEncoderClsid(L"image/png",&encoder); softwareBitmap.Save(L"d:\\image.png",&encoder); 

因此,我得到的图像填充的RGB值等于10 。 看来GDI +使用传统的algorithm:

255 *(10/255)+ 0 *(1-10 / 255)== 10。

但我期待预乘algorithm将被使用(因为前景图像具有预乘的PixelFormat32bppPARGB格式):

255 + 0 *(1-10 / 255)== 255

所以我的问题是,为什么GDI +使用传统的公式时图像是预乘alpha格式? 是否有任何解决方法,使GDI +使用预乘alphaalgorithm?

前景图像的格式不重要(因为它具有alpha),因为您将它设置为Gdiplus :: Color。 颜色值被定义为非预乘,因此gdiplus在清除前景图像时将其乘以alpha值。 另一种方法是根据渲染目标的格式,颜色值有不同的含义,这就是疯狂。

您可以通过直接设置源图像位来实现自己的目标,或者您可能不会。 值大于100%的组件在gdiplus的渲染模型中并不真正有效,所以如果在渲染过程中限制它们,我不会感到惊讶。 如果你真的想要这个级别的渲染控制,你将不得不锁定位图位,并自己做。