wrong alpha blending with CImage::AlphaBlend() & *.png

305 views
Skip to first unread message

thomas rehaag

unread,
Feb 27, 2009, 7:05:56 AM2/27/09
to
Hi,

I use the CImage class to load PNG file and do the alpha blending in a
dialog's OnPaint:

CImage m_imgTest;//in the header file

m_imgTest.Load(_T("test.png"));//in OnInitDialog

//In OnPaint:
CPaintDC dc(this);
m_imgBack.BitBlt((HDC)dc,0,0);//an other image as background
if(!m_imgTest.IsNull())
m_imgTest.AlphaBlend((HDC)dc,5,164);

Somehow the alpha blendig works - I can see the background throug some
parts of my test.png and completely transparent parts of test.png
ain't visible at all.
But there must be something wrong with the alpha function or the alpha
data: parts with a very low alpha are displayed as if they had a high
alpha.
I put the same pictures as back- and foreground into an html file and
started it in IExplore & FireFox. Both programs deliver alpha blending
as expected.

What am I doing wrong?

Best Regards & thanks in advance,

Thomas

thomas rehaag

unread,
Feb 27, 2009, 11:58:56 AM2/27/09
to
Problem solved. CImage::AlphaBlend() works fine with premultiplied
colour data.
Does anybody know if this is documented somewhere?

I overwrote CImage::Load() and now everything works fine:


HRESULT CImg::Load(LPCTSTR pszFileName, bool bPreMultiply)
{
HRESULT retRes = CImage::Load(pszFileName);
if(!IsNull() && bPreMultiply)
{
unsigned char * pCol = 0;
long lW = GetWidth();
long lH = GetHeight();
for(long ixy = 0; ixy < lH; ixy ++)
{
for(long ixx = 0; ixx < lW; ixx ++)
{
pCol = (unsigned char *)GetPixelAddress(ixx,ixy);
unsigned char alpha = pCol[3];
if(alpha < 255)
{
pCol[0] = ((pCol[0] * alpha) + 127) / 255;
pCol[1] = ((pCol[1] * alpha) + 127) / 255;
pCol[2] = ((pCol[2] * alpha) + 127) / 255;
}
}
}
}
return retRes;
}

mast...@gmail.com

unread,
Jun 3, 2014, 2:18:46 PM6/3/14
to
Thank you! I was having the exact same issue, and your solution solved my problem perfectly! Very strange blending artifacts were appearing, but now they are gone entirely. Something must be wrong with the math/rounding in the original code.
Reply all
Reply to author
Forward
0 new messages