2010-04-16 1 views
-1

J'ai un code de travail qui utilise IImgCtx pour charger des images, mais je n'arrive pas à trouver comment obtenir le canal alpha. Pour les images comme .gif et .png, il y a des pixels transparents, mais l'utilisation de n'importe quel autre bitmap 24 bits comme surface de dessin ne fonctionne pas.Comment utiliser IImgCtx pour charger une image avec un canal alpha?

Pour référence sur l'interface: http://www.codeproject.com/KB/graphics/JianImgCtxDecoder.aspx

Mon code ressemble à ceci:

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

Où "StartDC" enveloppe essentiellement CreateCompatibleDC (NULL) et "EndDC" encapsule DeleteDC, avec SelectObjects appropriés pour HBITMAPS etc. Et pDC-> Create (x, y, bit_depth) appelle CreateDIBSection (... DIB_RGB_COLORS ...). Donc, cela fonctionne si je crée un bitmap 24 bits/pixel, mais n'a pas d'alpha pour parler, et si je passe un bitmap 32 bits/pixel, il remplit les canaux de couleur RVB et laisse le canal alpha 0x00. Si je OU le canal alpha avec 0xff pour rendre l'image complètement opaque, il ressemble à l'option 24 bpp. Maintenant, cette interface est apparemment utilisée par Internet Explorer pour charger des images, et évidemment, cela supporte la transparence, donc je crois qu'il est possible d'obtenir un certain niveau d'alpha sur l'interface. La question est comment?

(j'ai aussi tomber le code de retour qui appellera libpng/libjpeg/mon chargeur .gif etc)

Répondre

1

GDI ne prend pas en charge les canaux alpha. Lorsque la méthode Draw est appelée pour PNG et GIF, une méthode de mélange alpha interne fonctionne, elle ne touche pas le canal alpha du bitmap sélectionné dans DC, elle combine uniquement les canaux de couleur en utilisant les données de canal alpha stockées en interne de l'image PNG \ GIF.

Pour les BMP 32 bits, la situation est très différente, il n'y a pas d'alpha-blending, tous les bits sont simplement copiés dans DC. Si la profondeur de bitmap sélectionnée dans DC et la profondeur de bits de bitmap à dessiner sur DC sont égales, alors dessiner sur DC est juste comme un appel de memcpy. C'est pourquoi parfois il y a une illusion que GDI supporte les canaux alpha, mais en fait c'est juste une copie stupide des octets et le canal alpha copié ne fait aucune différence dans l'image résultante. En d'autres termes, n'utilisez pas GDI ou toute bibliothèque basée dessus pour travailler avec des canaux alpha. Utilisez GDI +, environ 10 ans écoulés depuis sa sortie et il peut être trouvé presque sur tous les ordinateurs Windows.

Questions connexes