简体   繁体   English

C#将32bpp图像转换为8bpp

[英]C# Converting 32bpp image to 8bpp

I'm trying to convert a 32bpp screenshot image to an 8bpp (or 4bpp, or 1bpp) format using C#. 我正在尝试使用C#将32bpp屏幕截图图像转换为8bpp(或4bpp或1bpp)格式。 I've already looked at several stackoverflow answers on similar subjects and most suggest variations using the following code: 我已经查看了关于类似主题的几个stackoverflow答案,并且大多数使用以下代码提出了一些建议:

public static Bitmap Convert(Bitmap oldbmp) 
{
    Bitmap newbmp = new Bitmap(oldbmp.Width, oldbmp.Height, PixelFormat.Format8bppIndexed);

    Graphics gr = Graphics.FromImage(newbmp);

    gr.PageUnit = GraphicsUnit.Pixel;
    gr.DrawImageUnscaled(oldbmp, 0, 0);

    return newbmp;
}

However, when this executes, I get a the exception: A graphics object cannot be created from an image that has an indexed pixel format . 但是,执行此操作时,我得到一个例外: A graphics object cannot be created from an image that has an indexed pixel format I understand that 8, 4 and 1bpp images have colour table mappings rather than the actual colour pixels themselves (as in 32 or 16bpp images) so I assume I'm missing some conversion step somewhere, but I'm fairly new to C# (coming from a C++ background) and would prefer to be able do this using native C# calls rather than resorting to PInvoking BitBlt and GetDIBits etc. Anybody able to help me solve this? 我了解到8、4和1bpp图像具有颜色表映射,而不是实际的颜色像素本身(如32或16bpp图像),因此我假设我在某处缺少某些转换步骤,但对于C#来说还是很陌生(来自C ++背景),并且希望能够使用本地C#调用来做到这一点,而不是借助PInvoking BitBltGetDIBits等。有人能帮助我解决这个问题吗? Thanks. 谢谢。

EDIT : I should point out that I need this to be backwardly compatible to .NET framework 2.0 编辑 :我应该指出,我需要它与.NET Framework 2.0向后兼容

GDI+ in general has very poor support for indexed pixel formats. 通常,GDI +对索引像素格式的支持非常差。 There is no simple way to convert an image with 65536 or 16 million colors into one that only has 2, 16 or 256. Colors have to be removed from the source image and that is a lossy conversion that can have very poor results. 没有简单的方法可以将具有65536或1600万种颜色的图像转换为仅具有2、16或256种颜色的图像。必须从源图像中除去颜色,这是一种有损转换,可能会产生非常差的结果。 There are multiple algorithms available to accomplish this, none of them are perfect for every kind of image. 有多种算法可以实现此目的,但没有一种算法适合每种图像。 This is a job for a graphics editor. 这是图形编辑器的工作。

There is one trick I found. 我发现了一个窍门。 GDI+ has an image encoder for GIF files. GDI +具有用于GIF文件的图像编码器。 That's a graphics format that has only 256 colors, the encoder must limit the number of colors. 那是只有256种颜色的图形格式,编码器必须限制颜色的数量。 It uses a dithering algorithm that's suitable for photos. 它使用适合照片的抖动算法。 It does have a knack for generating a grid pattern, you'll be less than thrilled when it does. 它确实具有生成网格图案的诀窍,当您这样做时,您会不胜其烦。 Use it like this: 像这样使用它:

public static Image Convert(Bitmap oldbmp) {
    using (var ms = new MemoryStream()) {
        oldbmp.Save(ms, ImageFormat.Gif);
        ms.Position = 0;
        return Image.FromStream(ms);
    }
}

The returned image has a 8bpp pixel format with the Palette entries calculated by the encoder. 返回的图像具有8bpp像素格式,其中调色板项由编码器计算。 You can cast it to Bitmap if necessary. 您可以根据需要将其强制转换为Bitmap。 By far the best thing to do is to simply not bother with indexed formats. 到目前为止,最好的办法就是根本不用去理会索引格式。 They date from the stone age of computing back when memory was severely constrained. 它们可以追溯到计算的石器时代,当时内存受到严重限制。 Or use a professional graphics editor. 或使用专业的图形编辑器。

AForge library is doing it perfectly using Grayscale . AForge库使用Grayscale完美地做到了。

var bmp8bpp = Grayscale.CommonAlgorithms.BT709.Apply(bmp);

This class is the base class for image grayscaling [...] The filter accepts 24, 32, 48 and 64 bpp color images and produces 8 (if source is 24 or 32 bpp image) or 16 (if source is 48 or 64 bpp image) bpp grayscale image. 此类是图像灰度缩放的基础类。过滤器接受24、32、48和64 bpp彩色图像,并产生8(如果源是24或32 bpp图像)或16(如果源是48或64 bpp)图片)bpp灰度图片。

Negative stride signifies the image is bottom-up (inverted). 负的步幅表示图像自下而上(反转)。 Just use the absolute of the stride if you dont care. 如果您不在乎,请使用步幅的绝对值。 I know that works for 24bpp images, unaware if it works for others. 我知道这适用于24bpp图像,不知道它是否适用于其他人。

您可以使用System.Windows.Media.Imaging在PresentationCore大会看一看这里了解更多信息

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

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