简体   繁体   中英

Capturing an image on another form, how to maintain dpi with bitmaps

I am using the function below to capture an image on a different form. The captured image is then fed to an OCR app, in this instance tesseract. The issue that I am having is that when the image is copied to the bitmap the quality drops to 96dpi and I want to keep it either at 1 to 1 or at least 300 dpi and also scale it *2 as the text on the image is a little small. I did not write the capture function and am wondering if anyone has any recommendations as to how I can modify it to up the quality of the returned Bitmap.

I have since learnt that the default dpi of image captures is actually 96dpi, you can enlarge any text to 120dpi but that didn't really help in this instance. The only option is to capture the image and then resize it. So far I have found a couple of ways of doing this, one below which I modified to use stretchBlt and another which I create another larger bitmap and then bitblt it onto this new enlarged bitmap which has a higher dpi with this like bicubic scaling set to high. So far I am able to get a correct OCR rate of about 75 - 90% which isn't bad, but I didn't get the cookie.

public static Bitmap Capture(IntPtr hwnd, int x, int y, int width, int height)
        {
            //Size contains the size of the screen
            SIZE size;

            //hBitmap contains the handle to the bitmap
            IntPtr hBitmap;

            //Get handle to the desktop device context
            IntPtr hDC = PlatformInvokeUSER32.GetDC(hwnd);

            //Device context in memory for screen device context
            IntPtr hMemDC = PlatformInvokeGDI32.CreateCompatibleDC(hDC);

            //Pass SM_CXSCREEN to GetSystemMetrics to get the X coordinates 
            //of the screen
            size.cx = width;

            //As above but get Y corrdinates of the screen
            size.cy = height;

            //Create a compatiable bitmap of the screen size using the 
            //screen device context
            hBitmap = PlatformInvokeGDI32.CreateCompatibleBitmap(hDC, size.cx, size.cy);

            //Cannot check of IntPtr is null so check against zero instead
            if (hBitmap != IntPtr.Zero)
            {
                //Select the compatiable bitmap in the memeory and keep a 
                //refrence to the old bitmap
                IntPtr hOld = (IntPtr)PlatformInvokeGDI32.SelectObject(hMemDC, hBitmap);

                //Copy bitmap into the memory device context
                bool b = PlatformInvokeGDI32.BitBlt(hMemDC, 0, 0, size.cx, size.cy, hDC, x, y, PlatformInvokeGDI32.SRCOPY);

                //Select the old bitmap back to the memory device context
                PlatformInvokeGDI32.SelectObject(hMemDC, hOld);

                //Delete memory device context
                PlatformInvokeGDI32.DeleteDC(hMemDC);

                //Release the screen device context
                PlatformInvokeUSER32.ReleaseDC(hwnd, hDC);

                //Create image
                Bitmap bmp = System.Drawing.Image.FromHbitmap(hBitmap);

                //Release memory to avoid leaks
                PlatformInvokeGDI32.DeleteObject(hBitmap);

                //Run garbage collector manually
                GC.Collect();

                //Return the bitmap
                return bmp;

            }

            else
            {

                return null;

            }

        }

        #endregion

    }

Thanks R.

您可以使用StretchBlt ,而不是使用BitBlt。

Even though you could easily capture a bigger bitmap by blitting onto a larger target bitmap, you wouldn't really be getting any more detail, since you don't have access to the original image the form you're capturing from is displaying. You will always be limited to the resolution of the screen.

To clarify (since you say you are new), if you take an image that is 1200x1200 pixels and draw it to an area that is 120x120 pixels, then capture that area and draw it back to a bitmap that is also 1200x1200 pixels, you will have lost a whole lot of detail in the process. If you don't have access to the original image you can't recreate the lost pixels.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM