views:

38

answers:

2

Hi,

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.

+1  A: 

Instead of using BitBlt, you can use StretchBlt.

Zafer
thanks, would you have an example, and yes I did look at the link. Sorry but I am very new to this.
flavour404
I did manage to get StretchBlt working. It does maintain a very tight image, thanks for the headsup.
flavour404
I'm glad that it worked. By the way, don't forget to make accept the answer :).
Zafer
+1  A: 

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.

David