MFC CImage alpha混合错误

时间:2017-04-03 11:45:12

标签: image visual-c++ mfc png alphablending

我必须在一个由两个PNG文件组成的图片控件上呈现图像,其中顶部图像在某些位置上具有透明像素。

结果应该是plotter.png

enter image description here

with bar.png

enter image description here

顶部重叠显示为(注意栏上奇怪的白色轮廓):

enter image description here

但它应该是:

enter image description here

我为它制作的代码很简单

    CImage image;
    if (FAILED(image.Load(L"plotter.png")))
        return false;

    CImage imageBar;
    if (FAILED(imageBar.Load(L"bar.png")))
        return false;

    imageBar.AlphaBlend(image.GetDC(), CPoint());
    image.ReleaseDC();


    ((CStatic*)GetDlgItem(IDC_PICTURE))->SetBitmap(image);

我已阅读Alpha Blending a BitmapBLENDFUNCTION structure上的MSDN文档,并做了一些实验。一个细节让我盯着我引用的文字:

  

当位图具有Alpha通道时(即,   每像素alpha)。请注意,API使用预乘alpha,即   表示位图中的红色,绿色和蓝色通道值必须   与alpha通道值预乘。例如,如果   alpha通道值为x,红色,绿色和蓝色通道必须为   在调用之前乘以x并除以0xff。

Alphablend使用预乘alpha ,这意味着在加载后我必须转到位图并将每个像素乘以其自己的alpha。所以我试过

for (int i = 0; i < imageBar.GetWidth(); i++)
{
    for (int j = 0; j < imageBar.GetHeight(); j++)
    {
        BYTE* ptr = (BYTE*) imageBar.GetPixelAddress(i, j);
        ptr[0] = (ptr[0] * ptr[3]) / 255;
        ptr[1] = (ptr[1] * ptr[3]) / 255;
        ptr[2] = (ptr[2] * ptr[3]) / 255;
    }
}
AlphaBlend行之前

我所获得的仍然不尽如人意:(

那么,我怎样才能得到正确合成的图像呢?

1 个答案:

答案 0 :(得分:1)

经过几天的绝望之后,我终于找到http://forums.codeguru.com/showthread.php?420631-setting-CImage-alpha-values&p=1560260#post1560260这个解决方案类似于我尝试的解决方案,但每个像素的增加了127 ,是一件有用的东西,但当时我还没有理解,也没有做过任何努力来理解它。所以在AlphaBlend行之前现在有:

for (int i = 0; i < imageBar.GetWidth(); i++)
{
    for (int j = 0; j < imageBar.GetHeight(); j++)
    {
        BYTE* ptr = (BYTE*)imageBar.GetPixelAddress(i, j);
        ptr[0] = ((ptr[0] * ptr[3]) + 127) / 255;
        ptr[1] = ((ptr[1] * ptr[3]) + 127) / 255;
        ptr[2] = ((ptr[2] * ptr[3]) + 127) / 255;
    }
}

现在显示的图像组合得很好。