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

C#中SetPixel与GetPixel取值不一致问题求助

问题分析与解决方案

问题根源

  • JPEG是有损压缩格式,直接通过new Bitmap(文件名)加载JPEG时,.NET框架会自动处理JPEG的色彩空间转换(比如从YCbCr转RGB),这个过程会带来精度损失;后续调用Save()时,若使用默认参数,会再次进行有损压缩,双重损失导致像素值严重偏离设置值。
  • 两种加载方式的差异:Image.FromStream加载图像时,会保留原始解码数据,转Bitmap时采用的像素格式转换逻辑更严谨,减少了色彩损失;而直接new Bitmap(文件名)的默认加载逻辑会引入额外的色彩转换误差。

可行解决方案(基于必须使用new Bitmap(dlg.FileName)的前提)

1. 保存时使用最高质量JPEG参数

通过指定编码器参数,将JPEG压缩质量拉满,最大程度减少压缩带来的像素损失:

// 设置JPEG最高质量编码器参数
ImageCodecInfo jpegEncoder = ImageCodecInfo.GetImageEncoders()
    .FirstOrDefault(encoder => encoder.FormatID == ImageFormat.Jpeg.Guid);
EncoderParameters encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, 100L);

// 用指定参数保存Bitmap
bmp.Save("目标路径.jpg", jpegEncoder, encoderParams);

2. 加载后转换为32位ARGB格式

将加载后的Bitmap转换为无色彩损失的32位ARGB像素格式,避免后续操作中的色彩转换误差:

using (OpenFileDialog dlg = new OpenFileDialog())
{
    dlg.Filter = "jpg files (*.jpg)|*.jpg";
    if (dlg.ShowDialog() == DialogResult.OK)
    {
        using (Bitmap originalBmp = new Bitmap(dlg.FileName))
        {
            // 转换为32位ARGB格式,消除色彩空间转换损失
            bmp = new Bitmap(originalBmp.Width, originalBmp.Height, PixelFormat.Format32bppArgb);
            using (Graphics g = Graphics.FromImage(bmp))
            {
                g.DrawImage(originalBmp, new Rectangle(0, 0, originalBmp.Width, originalBmp.Height));
            }
        }
        textBox2.Text = dlg.FileName;
    }
}

3. 改用无损格式存储(优先推荐)

如果业务允许,放弃JPEG格式,改用PNG这种无损压缩格式存储图像,彻底避免压缩导致的像素值偏差:

// 保存为PNG,完全保留像素信息
bmp.Save("目标路径.png", ImageFormat.Png);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 04:27:14