You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中打开位图时保留原PixelFormat不被转换?

解决C#加载8bppIndexed格式PNG时自动转换像素格式的问题

问题原因

使用new Bitmap("myImage.png")加载8bppIndexed格式的PNG时,GDI+会自动将其转换为32bppRgb格式,这是默认的优化行为;而1bppIndexed格式的图像因为是黑白单色,不会触发该转换。

解决方案

方法1:基于System.Drawing的手动流加载(无需额外程序集)

通过文件流读取图像,再克隆为原始像素格式,绕过自动转换逻辑:

using System.IO;
using System.Drawing;

// 读取文件流
using (var fileStream = new FileStream("myImage.png", FileMode.Open))
{
    // 加载图像时禁用颜色管理与数据验证
    using (var sourceImage = Image.FromStream(fileStream, false, false))
    {
        // 克隆图像以保留原始像素格式
        Bitmap originalFormatBitmap = sourceImage.Clone(
            new Rectangle(0, 0, sourceImage.Width, sourceImage.Height),
            sourceImage.PixelFormat
        );
        
        // 此时originalFormatBitmap.PixelFormat为Format8bppIndexed,可直接用于你的海龟图形处理代码
    }
}

方法2:使用WPF的PngBitmapDecoder(保留原始格式更可靠)

如果项目允许引用PresentationCore和WindowsBase程序集,可直接读取原始索引格式:

using System.IO;
using System.Drawing;
using System.Windows.Media.Imaging;

using (var fileStream = new FileStream("myImage.png", FileMode.Open))
{
    // 解码器指定保留原始像素格式
    var decoder = new PngBitmapDecoder(
        fileStream,
        BitmapCreateOptions.PreservePixelFormat,
        BitmapCacheOption.OnLoad
    );
    var imageFrame = decoder.Frames[0];
    
    // 若需要转换为System.Drawing.Bitmap供现有代码使用
    using (var memoryStream = new MemoryStream())
    {
        var encoder = new PngBitmapEncoder();
        encoder.Frames.Add(imageFrame);
        encoder.Save(memoryStream);
        memoryStream.Position = 0;
        
        Bitmap indexedBitmap = new Bitmap(memoryStream);
        // 此时indexedBitmap.PixelFormat为Format8bppIndexed
    }
}

注意事项

  • 方法1中Image.FromStream的后两个参数设为false,是为了避免颜色管理和数据验证导致的格式转换;
  • 方法2需要添加对PresentationCore.dll和WindowsBase.dll的引用,适合WPF项目或允许引入这些程序集的WinForms项目。

内容的提问来源于stack exchange,提问作者Hammerite

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 08:42:24