views:

1613

answers:

2

I have an HBITMAP containing alpha channel data. I can successfully render this using the ::AlphaBlend GDI function.

However, when I call the ::GetPixel GDI function, I never get back values with an alpha component. The documentation does say that it returns the RGB value of the pixel.

Is there a way to retrieve the alpha channel values for pixels in an HBITMAP?

I want to be able to detect when to use ::AlphaBlend, and when to use an old-school method for treating a particular colour in the source HBITMAP as transparent.


HDC sourceHdc = ::CreateCompatibleDC(hdcDraw);
::SelectObject(sourceHdc, m_hbmp);

// This pixel has partial transparency, but ::GetPixel returns just RGB.
COLORREF c = ::GetPixel(sourceHdc, 20, 20);

// Draw the bitmap to hdcDraw
BLENDFUNCTION bf1;
bf1.BlendOp = AC_SRC_OVER;
bf1.BlendFlags = 0;
bf1.SourceConstantAlpha = 0xff;  
bf1.AlphaFormat = AC_SRC_ALPHA;            
::AlphaBlend(di.hdcDraw, x, 10, 64, 64, sourceHdc, 0, 0, 64, 64, bf1);

::DeleteDC(sourceHdc);


Answer

Use GetDIBits to retrieve the first (or more) scan line(s) of the image:

  byte* bits[1000];// = new byte[w * 4]; 
  BITMAPINFO bmi;
  memset(&bmi, 0, sizeof(BITMAPINFO)); 
  bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  bmi.bmiHeader.biWidth = w;
  bmi.bmiHeader.biHeight = -h;
  bmi.bmiHeader.biBitCount = 32;
  bmi.bmiHeader.biPlanes = 1;
  bmi.bmiHeader.biCompression = BI_RGB;
  bmi.bmiHeader.biSizeImage     = 0;
  bmi.bmiHeader.biXPelsPerMeter = 0;
  bmi.bmiHeader.biYPelsPerMeter = 0;
  bmi.bmiHeader.biClrUsed       = 0;
  bmi.bmiHeader.biClrImportant  = 0;
  int rv = ::GetDIBits(sourceHdc1, m_hbmp, 0, 1, (void**)&bits, &bmi, DIB_RGB_COLORS);

  //bits[3] == alpha of topleft pixel;

  //delete[] bits;
+4  A: 

Use GetDIBits. That way you get an array of RGBQUAD's which have as you can probably guess an alpha channel next to the R, G and B components.

Roel
Thanks! I just found that and was coming back to update the question with the answer. (Honest)
mackenir
A: 

Hi, i am trying to get bitmap from mouse cursor. But with next code, i just can't get colors. Can you give me little help about this?

  CURSORINFO cursorInfo = { 0 };
    cursorInfo.cbSize = sizeof(cursorInfo);

    if (GetCursorInfo(&cursorInfo))  {

        ICONINFO ii = {0};
        int p = GetIconInfo(cursorInfo.hCursor, &ii);

        // get screen
        HDC dc = GetDC(NULL);
        HDC memDC = CreateCompatibleDC(dc);
        //SelectObject(memDC, ii.hbmColor);

        int counter = 0;

        //
        byte* bits[1000];// = new byte[w * 4]; 
          BITMAPINFO bmi;
          memset(&bmi, 0, sizeof(BITMAPINFO)); 
          bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
          bmi.bmiHeader.biWidth = 16;
          bmi.bmiHeader.biHeight = 16;
          bmi.bmiHeader.biBitCount = 32;
          bmi.bmiHeader.biPlanes = 1;
          bmi.bmiHeader.biCompression = BI_RGB;
          bmi.bmiHeader.biSizeImage     = 0;
          bmi.bmiHeader.biXPelsPerMeter = 0;
          bmi.bmiHeader.biYPelsPerMeter = 0;
          bmi.bmiHeader.biClrUsed       = 0;
          bmi.bmiHeader.biClrImportant  = 0;
          int rv = ::GetDIBits(memDC, ii.hbmColor, 0, 1, (void**)&bits, &bmi, DIB_RGB_COLORS);
    }
Nikola
I would recommend posing this as a question of its own, @Nikola.
mackenir
Hi, thank you very much. I posted new question on http://stackoverflow.com/questions/3830698/mouse-cursor-bitmap.
Nikola