简体   繁体   English

在另一个表单上捕获图像,如何使用位图维护dpi

[英]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. 然后将捕获的图像馈送到OCR应用程序,在本例中为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. 我遇到的问题是,当图像被复制到位图时,质量下降到96dpi,我想保持它为1到1或至少300 dpi,并且还要缩放它* 2,因为图像上的文字是有点小。 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. 我已经了解到图像捕获的默认dpi实际上是96dpi,你可以将任何文本放大到120dpi,但这在这个实例中并没有真正帮助。 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. 到目前为止,我已经找到了两种方法来实现这一点,一个是我修改为使用stretchBlt,另一个是我创建了另一个更大的位图,然后将它bitblt到这个新的放大位图上,这个位图具有更高的dpi,就像这样的双三次缩放设置为高。 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. 到目前为止,我能够获得大约75-90%的正确OCR率,这也不错,但我没有得到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. 谢谢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. 即使您可以通过blitting到更大的目标位图来轻松捕获更大的位图,您也不会真正获得更多细节,因为您无法访问正在捕获的表单正在显示的原始图像。 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. 为了澄清(因为你说你是新的),如果你拍摄1200x1200像素的图像并将其绘制到120x120像素的区域,然后捕获该区域并将其绘制回也是1200x1200像素的位图,你将在这个过程中失去了很多细节。 If you don't have access to the original image you can't recreate the lost pixels. 如果您无法访问原始图像,则无法重新创建丢失的像素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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