Search code examples
c#wpfgdibitmapsource

Remove alpha from a BitmapSource


I use BitBlt() and CreateBitmapSourceFromHBitmap() to capture a window as a BitmapSource that I can display on an Image element in a WPF application. But for some reason, most of the application that it captures is transparent. Here is a source vs. capture image of what's happening:

https://userpages.umbc.edu/~smyth1/images/screencap.PNG
(source: umbc.edu)

It's gray because the background of the window it's on is gray. Whatever background I give the window will show through.

How can I get the captured image to more accurately reflect the original?


Solution

  • The problem in your code could be due to the Win32 API you're using (CreateCompatibleDC, SelectObject, CreateBitmap...). I tried with a simpler code, using only GetDC and BitBlt, and it works fine for me. Here's my code:

        public static Bitmap Capture(IntPtr hwnd)
        {
            IntPtr hDC = GetDC(hwnd);
            if (hDC != IntPtr.Zero)
            {
                Rectangle rect = GetWindowRectangle(hwnd);
                Bitmap bmp = new Bitmap(rect.Width, rect.Height);
                using (Graphics destGraphics = Graphics.FromImage(bmp))
                {
                    BitBlt(
                        destGraphics.GetHdc(),
                        0,
                        0,
                        rect.Width,
                        rect.Height,
                        hDC,
                        0,
                        0,
                        TernaryRasterOperations.SRCCOPY);
                }
                return bmp;
            }
            return null;
        }
    

    I tried it in Windows Forms and WPF (with Imaging.CreateBitmapSourceFromHBitmap), it works fine in both cases for the same screenshot (SO page in Firefox).

    HTH,