2

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

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 算法?

4

1 回答 1

1

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

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

于 2013-11-09T00:42:17.670 回答