2010-04-16 58 views
-1

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

关于接口的参考: 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,用适当的SelectObjects HBITMAPS等。并且pDC-> Create(x,y,bit_depth)调用CreateDIBSection(... DIB_RGB_COLORS ...)。因此,如果我创建24位/像素位图,但没有可用的字母,并且如果我传递了32位/像素位图,它将填充RGB颜色通道并保留Alpha通道0x00。如果我使用0xff的alpha通道将图像设置为完全不透明,那么它看起来与24 bpp选项相同。现在这个界面显然被Internet Explorer用来加载图片,显然THAT支持透明度,所以我相信可以从界面中获得一些alpha级别。问题是如何?

(我也有回落的代码,将调用的libpng/libjpeg的/我的.gif注意装载机等)

回答

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计算机上找到它。

相关问题