MFC CImage alpha混合出错
我必须在图片控件上显示由两个PNG文件组成的图像,上面的图像在某些位置上有透明像素 结果应该是plotter.png的结果 使用bar.png 顶部重叠显示为(请注意条上奇怪的白色轮廓): 但它应该是: 我为它编写的代码很简单MFC CImage alpha混合出错,image,visual-c++,mfc,png,alphablending,Image,Visual C++,Mfc,Png,Alphablending,我必须在图片控件上显示由两个PNG文件组成的图像,上面的图像在某些位置上有透明像素 结果应该是plotter.png的结果 使用bar.png 顶部重叠显示为(请注意条上奇怪的白色轮廓): 但它应该是: 我为它编写的代码很简单 CImage image; if (FAILED(image.Load(L"plotter.png"))) return false; CImage imageBar; if (FAILED(imageBar.Lo
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);
我已经阅读了和的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;
}
}
for(int i=0;i
在AlphaBlend
行之前,我得到的仍然不令人满意:(
那么,我怎样才能得到正确的构图呢?经过几天几夜的绝望,我终于找到了一个类似于我尝试过的解决方案,但在每个像素上增加了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;
}
}
for(int i=0;i
现在显示的图像合成良好。请确保您的PNG文件是24位的,因为8位PNG不支持透明度。