MFC CImage alpha blending gone wrong

喜欢而已 提交于 2019-12-20 04:21:06

问题


I have to present images on a picture control that are a composition of two PNG files, where the top image has transparent pixels on certain positions.

The result should of plotter.png

with bar.png

overlapped on its top appears as (Notice the strange white contours on the bar):

but it should be:

The code I made for it is simple as

    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);

I have read the MSDN documentation on Alpha Blending a Bitmap and BLENDFUNCTION structure and did some experiments. A detail made me stare on the text I am quoting:

This flag is set when the bitmap has an Alpha channel (that is, per-pixel alpha). Note that the APIs use premultiplied alpha, which means that the red, green and blue channel values in the bitmap must be premultiplied with the alpha channel value. For example, if the alpha channel value is x, the red, green and blue channels must be multiplied by x and divided by 0xff prior to the call.

Alphablend uses premultiplied alpha, which means after loading I have to go to the bitmap and multiply every pixel by its own alpha. So I tried

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;
    }
}

before the AlphaBlendline and what I've got is still not satisfactory :(

So, how can I get a correctly composed image?


回答1:


After some days and night of desperation, I've finally found http://forums.codeguru.com/showthread.php?420631-setting-CImage-alpha-values&p=1560260#post1560260 which a solution similar to what I've tried, but with the addition of 127 to every pixel, which is a thing that worked but I've not understood at the time, nor I had made any effort to understand it yet. So before the AlphaBlend line now there is:

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;
    }
}

and now the displayed image is well composed.



来源:https://stackoverflow.com/questions/43183799/mfc-cimage-alpha-blending-gone-wrong

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!