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

时间:2013-11-06 10:24:38

标签: windows gdi+

以下是一些显示问题的最小代码:

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 +使用传统算法:

  

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

但是我期待使用预乘算法(因为前景图像具有预乘PixelFormat32bppPARGB格式):

  

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

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

1 个答案:

答案 0 :(得分:1)

前景图像的格式无关紧要(假设它具有alpha),因为您将其设置为Gdiplus :: Color。颜色值定义为非预乘,因此gdiplus在清除前景图像时将组件乘以alpha值。另一种选择是Color值具有不同的含义,具体取决于渲染目标的格式,这种方式就是疯狂。

您可以通过直接设置源图像位来执行您想要的操作,或者您可能不会。值大于100%的组件在gdiplus的渲染模型中并不真正有效,因此如果在渲染过程中限制它们,我不会感到惊讶。如果您真的希望对渲染进行这种级别的控制,则必须锁定位图位并自行完成。