首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C#将32 8bpp图像转换为8bpp

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

Stack Overflow用户
提问于 2011-06-15 08:45:05
回答 4查看 18.2K关注 0票数 17

我正试图使用C#将32 8bpp的屏幕截图图像转换为8bpp(或4bpp或1bpp)格式。我已经看过关于类似主题的几个堆栈溢出答案,并且大多数建议使用以下代码进行更改:

代码语言:javascript
复制
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;
}

但是,当执行时,我会得到一个异常:A graphics object cannot be created from an image that has an indexed pixel format。我知道8、4和1bpp图像有颜色表映射,而不是实际的颜色像素本身(比如32或16bpp图像),所以我假设我在某个地方遗漏了一些转换步骤,但我对C# (来自C++背景)相当陌生,我更希望能够使用本地C#调用来实现这一点,而不是求助于PInvoking BitBltGetDIBits等。有谁能帮我解决这个问题呢?谢谢。

编辑:我应该指出,我需要向后兼容.NET框架2.0

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-06-15 10:10:17

一般来说,GDI+对索引像素格式的支持非常差。要将65536或1600万种颜色的图像转换为只有2、16或256个颜色的图像,没有简单的方法。颜色必须从源图像中移除,这是一种有损转换,结果可能非常糟糕。有多种算法可以实现这一点,没有一个是完美的每种类型的图像。这是图形编辑器的工作。

我发现了一个诡计。GDI+有一个用于GIF文件的图像编码器。这是一种只有256种颜色的图形格式,编码器必须限制颜色的数量。它使用了一种适合于照片的抖动算法。它确实有生成网格模式的诀窍,当它生成的时候,你就不会那么兴奋了。像这样使用它:

代码语言:javascript
复制
public static Image Convert(Bitmap oldbmp) {
    using (var ms = new MemoryStream()) {
        oldbmp.Save(ms, ImageFormat.Gif);
        ms.Position = 0;
        return Image.FromStream(ms);
    }
}

返回的图像具有8bpp像素格式,由编码器计算调色板条目。如果有必要,可以将其转换为位图。到目前为止,最好的做法就是不使用索引格式。它们可以追溯到计算的石器时代,当时内存受到严重限制。或者使用专业的图形编辑器。

票数 16
EN

Stack Overflow用户

发布于 2016-03-11 14:13:04

AForge库正在使用灰度完美地完成它。

代码语言:javascript
复制
var bmp8bpp = Grayscale.CommonAlgorithms.BT709.Apply(bmp);

这个类是图像灰度缩放的基类.该滤波器接受24、32、48和64 bpp彩色图像,并产生8 (if源为24或32 bpp图像)或16 (如果源为48或64 bpp图像) bpp灰度图像。

票数 10
EN

Stack Overflow用户

发布于 2011-09-01 19:37:27

负步幅表示图像是自下而上(倒置).如果你不在乎的话,就用绝对的步幅。我知道这适用于24bpp图像,不知道它是否适用于其他人。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6355135

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档