C#中捕获屏幕为8位(256色)的位图 [英] C# Capture screen to 8-bit (256 color) bitmap

查看:373
本文介绍了C#中捕获屏幕为8位(256色)的位图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用这个code捕捉画面:

I'm using this code to capture the screen:

public Bitmap CaptureWindow(IntPtr handle)
{
    // get te hDC of the target window
    IntPtr hdcSrc = User32.GetWindowDC(handle);
    // get the size
    User32.RECT windowRect = new User32.RECT();
    User32.GetWindowRect(handle, ref windowRect);
    int width = windowRect.right - windowRect.left;
    int height = windowRect.bottom - windowRect.top;
    // create a device context we can copy to
    IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
    // create a bitmap we can copy it to,
    // using GetDeviceCaps to get the width/height
    IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
    // select the bitmap object
    IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
    // bitblt over
    GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY);
    // restore selection
    GDI32.SelectObject(hdcDest, hOld);
    // clean up 
    GDI32.DeleteDC(hdcDest);
    User32.ReleaseDC(handle, hdcSrc);
    // get a .NET image object for it
    Bitmap img = Image.FromHbitmap(hBitmap);
    // free up the Bitmap object
    GDI32.DeleteObject(hBitmap);
    return img;
}

我然后想将位图转换成256色(8位)。我想这code,但获取不能够从索引位图格式创建图像的错误:

I then want to convert the bitmap to 256 colors (8 bit). I tried this code but get an error about not being able to create an Image from an indexed bitmap format:

Bitmap img8bit = new Bitmap(img.Width,img.Height,
                           System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
Graphics g = Graphics.FromImage(img8bit);
g.DrawImage(img,new Point(0,0));

我确实看到了一些例子来转换不同格式之间的位图,但对我来说,我在寻找做到这一点,而从屏幕上获取的最佳途径。例如,如果有一个,将更好地工作通过创建一个8比特的位图开始与和然后的blit屏幕以该方法中,这将是pferred超过caputring屏幕comptible位图,然后再将其转换$ P $。除非它更好地捕捉然后将其转换反正。

I did see some examples to convert bitmaps between different formats, but in my case I'm looking for the best way to do this while capturing from the screen. For example, if there is a method that will work better by creating an 8-bit bitmap to begin with and then blit the screen to that, that would be preferred over caputring screen to comptible bitmap first and then converting it. Unless it's better to capture then convert anyway.

我有一个程序用C ++编写使用Borland生成器6.0 VCL,和我想memic的。在这种情况下,它是设置像素格式为VCL的TBitmap对象的一个​​简单的事情。我注意到Bitmap.PixelFormat是只读的。NET,唉。

I have a program written in C++ using Borland Builder 6.0 VCL, and I'm trying to memic that. In that case it is a simple matter of setting the pixel format for VCL's TBitmap object. I notice Bitmap.PixelFormat is read-only in .NET, ugh.

更新:对我来说,我不认为答案是复杂的,需要找出最好的调色板项,因为使用Graphics.GetHalftonePalette屏幕DC要细一些其他的用途,因为我原来的位图来自于屏幕上,不是任何随机的位图,它可能来自一个文件/电子邮件/下载/等。我beleive有一些可以与也许20行code,涉及到的DIB和GetHalftonePalette做 - 只是无法找到它尚未

Update: In my case I don't think the answer is as complex as some other usage that requires figuring out the best palette entries, because Graphics.GetHalftonePalette using the screen DC should be fine, since my original bitmap comes from the screen, not just any random bitmap that might come from a file/email/download/etc. I beleive there is something that can be done with maybe 20 lines of code that involves DIBs and GetHalftonePalette -- just can't find it yet.

推荐答案

转换全彩色位图8bpp是一个很难操作。它需要创建的图像中的所有颜色的直方图并创建包含的颜色最好映射到原始颜色一组优化的调色板。然后,使用的技术像抖动或误差扩散,以取代其颜色的像素不具有与面板完全匹配。

Converting a full color bitmap to 8bpp is a difficult operation. It requires creating a histogram of all the colors in the image and creating a palette that contains an optimized set of colors that best map to the original colors. Then using a technique like dithering or error diffusion to replace the pixels whose colors don't have an exact match with the palette.

这是最好留给专业图形库,像ImageTools。还有就是可以在.NET框架被骗1廉价的方式。您可以使用GIF EN codeR,有256种颜色的文件格式。其结果是不是最大的,它使用的抖动,并且可以pretty的可见的时候。话又说回来,如果你真的在乎图像质量,那么你就不会使用8bpp反正。

This is best left to a professional graphics library, something like ImageTools. There is one cheap way that can be tricked in the .NET framework. You can use the GIF encoder, a file format that has 256 colors. The result isn't the greatest, it uses dithering and that can be pretty visible sometimes. Then again, if you really cared about image quality then you wouldn't use 8bpp anyway.

    public static Bitmap ConvertTo8bpp(Image img) {
        var ms = new System.IO.MemoryStream();   // Don't use using!!!
        img.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
        ms.Position = 0;
        return new Bitmap(ms);
    }

这篇关于C#中捕获屏幕为8位(256色)的位图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆