bitmap.save 将其 pixelFormat 更改为 32 位深度

Posted

技术标签:

【中文标题】bitmap.save 将其 pixelFormat 更改为 32 位深度【英文标题】:bitmap.save changes its pixelFormat to 32-bit depth 【发布时间】:2016-07-24 13:35:55 【问题描述】:

我遇到了一个我无法解决的问题,所以我决定问问你们。

我有非常简单的代码:

public void OpenSaveImageDialog(Bitmap bitmapImage)
    
        var dlg = new SaveFileDialog
        
            DefaultExt = DialogType.Image.defaultExt,
            Filter = DialogType.Image.filter
        ;

        dlg.ShowDialog();

        bitmapImage.Save(dlg.FileName);
    

函数参数是一个像素格式等于 24bppRgb 的位图。在保存操作期间,保留 pixelFormat 和位深度对我来说非常重要。但是在我保存文件并检查其属性后,它被保存为 32 位深度图像。这是为什么?如何解决这个问题?

谢谢。

【问题讨论】:

设置 ImageFormat 以在 24 位或 32 位格式之间进行选择:msdn.microsoft.com/en-us/library/9t4syfhh(v=vs.110).aspx 您将图像保存为 PNG 文件格式。是的,PNG 编解码器始终使用 32bpp。使用可让您指定 ImageFormat 的 Save() 方法重载,您可能更喜欢 Bmp。确保文件扩展名匹配,水晶球说现在不匹配。 谢谢,但它不起作用。我之前尝试过将保存替换为: bitmapImage.Save(dlg.FileName, ImageFormat.Bmp);但它不起作用。它也保存为 bmp,并且不保持像素格式。 那么您创建的 Bitmap 对象是错误的,并且您认为它是 24bpp 的假设是不正确的。当您不使用指定 PixelFormat 的 Bitmap 构造函数重载时,您获得的默认值与您的视频适配器匹配。在任何现代机器上总是 32bpp。 哦,我真的认为我的假设是正确的。让我这样说:i.imgur.com/GGVrDNN.png 如您所见。我用 24bpp 的位图打开我的保存对话框,用保存方法保存它(添加 ImageFormat.Bmp 没有区别),然后我用我的代码打开它,PixelFormat 已经改变。还在 Windows 资源管理器中检查过。 【参考方案1】:

您可以使用以下扩展方法保存为Format24bppRgb

public static class ImageExtensions

    public static Bitmap ImageTo24bpp(this Image img)
    
        var bmp = new Bitmap(img.Width, img.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
        using (var gr = Graphics.FromImage(bmp))
            gr.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height));
        return bmp;
    

如何使用并保存到名为 fname 的文件中:

        var image = bitmapImage.ImageTo24bpp();
        //convert image to bytes[]
        ImageConverter imgCon = new ImageConverter();
        var bytes=  (byte[])imgCon.ConvertTo(image, typeof(byte[]));
        //save to filename
        File.WriteAllBytes(fname,bytes);

编辑2:

您可以使用以下方法将图像保存为ImageTo24bpp

public void    SaveAsImageTo24bpp( Image img,string fname)
    
        var bmp = new Bitmap(img.Width, img.Height, PixelFormat.Format24bppRgb);
        using (var gr = Graphics.FromImage(bmp))
            gr.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height));         

        ImageConverter imgCon = new ImageConverter();
        var bytes = (byte[])imgCon.ConvertTo(bmp, typeof(byte[]));
         File.WriteAllBytes(fname,bytes);
    

【讨论】:

您的解决方案确实有效。奇怪的是我必须这样转换。我将具有相同像素格式的位图作为参数,并且可以通过保留此信息来保存它。这很奇怪......我想知道,为什么图像大小会改变?在我使用您的方法保存以前为 90 字节的 3x3 像素的图像后,新的图像大小为 137 字节。这种变化从何而来?我知道这可能很愚蠢,但知道这些事情对我的工作来说是必不可少的,嗯。 转换前/后保存图片的扩展名 对于24位图像(24bppRgb),我打开一个是32x27px和2,58kb的,然后用这种方法保存后它是231B o.0。 我已经对其进行了进一步测试,并且在保存后具有许多相同颜色的 ~800x600 24bpp 位图(仅在 ms paint 中绘制了正方形)被压缩到具有相同分辨率的 5,37kb。对我来说,它看起来不像是 bmp 图像 o.o 我修改了代码,试试看。转储新旧文件的结果,并在painter中查看。

以上是关于bitmap.save 将其 pixelFormat 更改为 32 位深度的主要内容,如果未能解决你的问题,请参考以下文章

从 VB 转换为 C#:bitmap.save() 参数错误

Winform中将Bitmap对象通过picture显示图片

C# Bitmap.Save 将图像作为路径保存到其他位置

如何使用Pillow从图像创建位图而不保存图像?

如何访问网站外的图片

将位图保存为任何格式