如何使用IImgCtx加载带有Alpha通道的图像?

时间:2010-04-16 04:55:42

标签: transparency

我有一些使用IImgCtx加载图像的工作代码,但我无法弄清楚如何获得alpha通道。对于像.gif和.png这样的图像,有透明像素,但使用24位图以外的任何图形作为绘图表面都不起作用。

有关界面的参考: http://www.codeproject.com/KB/graphics/JianImgCtxDecoder.aspx

我的代码如下所示:

IImgCtx *Ctx = 0;
HRESULT hr = CoCreateInstance(CLSID_IImgCtx, NULL, CLSCTX_INPROC_SERVER, IID_IImgCtx, (LPVOID*)&Ctx);
if (SUCCEEDED(hr))
{
    GVariant Fn = Name;
    hr = Ctx->Load(Fn.WStr(), 0);
    if (SUCCEEDED(hr))
    {
        SIZE  Size = { -1, -1 };
        ULONG State = 0;

        while (true)
        {
            hr = Ctx->GetStateInfo(&State, &Size, false);
            if (SUCCEEDED(hr))
            {
                if ((State & IMGLOAD_COMPLETE) || (State & IMGLOAD_STOPPED) || (State & IMGLOAD_ERROR))
                {
                    break;
                }
                else
                {
                    Sleep(1);
                }
            }
            else break;
        }

        if (Size.cx > 0 &&
            Size.cy > 0 &&
            pDC.Reset(new GMemDC))
        {
            if (pDC->Create(Size.cx, Size.cy, 32))
            {
                HDC hDC = pDC->StartDC();
                if (hDC)
                {
                    RECT rc = { 0, 0, pDC->X(), pDC->Y() };
                    Ctx->Draw(hDC, &rc);
                    pDC->EndDC();
                }
            }
            else pDC.Reset();
        }
    }

    Ctx->Release();

其中“StartDC”基本上包装CreateCompatibleDC(NULL)并且“EndDC”包装DeleteDC,并为HBITMAPS等提供适当的SelectObjects。并且pDC-> Create(x,y,bit_depth)调用CreateDIBSection(... DIB_RGB_COLORS .. )。所以它可以工作,如果我创建一个24位/像素位图,但没有alpha可以说,如果我传递32位/像素位图,它填充RGB颜色通道,并离开alpha通道0x00。如果我使用0xff的alpha通道将图像设置为完全不透明,那么它看起来与24 bpp选项相同。现在这个界面显然被Internet Explorer用来加载图像,显然这支持透明度,所以我相信可以从界面中获得某种程度的alpha。问题是如何?

(我也有回调代码,可以调用libpng / libjpeg / my .gif loader等)

1 个答案:

答案 0 :(得分:1)

GDI不支持Alpha频道。当为PNG和GIF调用Draw方法时,一些内部alpha混合方法可以使其工作,它不会触及在DC中选择的位图的alpha通道,它只使用内部存储的PNG \ GIF图像的alpha通道数据组合颜色通道。

对于32位BMP,情况完全不同,没有alpha混合,所有位都只是复制到DC。如果在DC中选择的位图的位深度和要在DC上绘制的位图的位深度匹配,则在DC上绘制就像一个memcpy调用。这就是为什么有时GDI支持alpha通道的错觉,但实际上这只是对字节的愚蠢复制和复制的alpha通道不会对结果图像产生任何影响。

换句话说,不要使用GDI或基于它的任何库来处理alpha通道。使用GDI +,自发布以来已过去约10年,几乎可以在所有Windows计算机上找到它。