Question

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?

Was it helpful?

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,

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top