Image.Save()用于jpeg文件的质量等级是多少?

Ste*_*e K 33 c# gdi+ system.drawing.imaging

当我加载一个jpg文件然后转过来并以100的质量保存它并且大小几乎是原始的4倍时,我才真正感到惊讶.为了进一步研究我打开并保存而没有明确设置质量和文件大小完全相同.我认为这是因为没有改变所以它只是将完全相同的位写回文件.为了测试这个假设,我在图像上对角线画了一条大胖线并再次保存而没有设置质量(这次我希望文件跳起来因为它会"脏")但它减少了~10Kb!

此时我真的不明白当我简单地调用Image.Save()时指出压缩质量时发生了什么.当我将质量设置为100(基本上没有压缩)时文件大小比原始大几倍时,文件大小如何接近(在图像修改后)到原始大小时尚未设置质量?

我已经阅读了有关Image.Save()的文档,而且它缺乏关于幕后发生的事情的任何细节.我用谷歌搜索了我能想到的每一种方式,但我找不到任何可以解释我所看到的信息的其他信息.我已经连续工作了31个小时,所以也许我错过了一些明显的东西; 0)

所有这些都是在我实现一些库方法将图像保存到数据库时实现的.我已经重载了我们的"SaveImage"方法以允许明确地设置质量,并且在我的测试期间,我遇到了上面解释的奇怪(对我而言)的结果.任何你可以流下的光都将受到赞赏.

这里有一些代码可以说明我遇到的情况:

string filename = @"C:\temp\image testing\hh.jpg";
string destPath = @"C:\temp\image testing\";

using(Image image = Image.FromFile(filename))
{
    ImageCodecInfo codecInfo = ImageUtils.GetEncoderInfo(ImageFormat.Jpeg);

    //  Set the quality
    EncoderParameters parameters = new EncoderParameters(1);

    // Quality: 10
    parameters.Param[0] = new EncoderParameter(
        System.Drawing.Imaging.Encoder.Quality, 10L);
    image.Save(destPath + "10.jpg", codecInfo, parameters);

    // Quality: 75
    parameters.Param[0] = new EncoderParameter(
        System.Drawing.Imaging.Encoder.Quality, 75L);
    image.Save(destPath + "75.jpg", codecInfo, parameters);

    // Quality: 100
    parameters.Param[0] = new EncoderParameter(
        System.Drawing.Imaging.Encoder.Quality, 100L);
    image.Save(destPath + "100.jpg", codecInfo, parameters);

    //  default
    image.Save(destPath + "default.jpg", ImageFormat.Jpeg);

    //  Big line across image
    using (Graphics g = Graphics.FromImage(image))
    {
        using(Pen pen = new Pen(Color.Red, 50F))
        {
            g.DrawLine(pen, 0, 0, image.Width, image.Height);
        }
    }

    image.Save(destPath + "big red line.jpg", ImageFormat.Jpeg);
}

public static ImageCodecInfo GetEncoderInfo(ImageFormat format)
{
    return ImageCodecInfo.GetImageEncoders().ToList().Find(delegate(ImageCodecInfo codec)
    {
        return codec.FormatID == format.Guid;
    });
}
Run Code Online (Sandbox Code Playgroud)

Oha*_*der 19

使用反射器,结果是Image.Save()归结为GDI +函​​数GdipSaveImageToFile,使用encoderParamsNULL.所以我认为问题是JPEG编码器在获得null时会做什么encoderParams.这里建议75%,但我找不到任何可靠的参考.

编辑您可以通过运行上面的程序获得1..100的质量值并将它们与使用默认质量保存的jpg进行比较(例如,使用fc.exe/B)

  • 我做了一个快速测试并打开了一个*.bmp文件,然后使用默认设置保存到jpg,并且质量明确设置为75.文件大小完全相同.所以它必须是编码器在内部默认为75.我认为这应该在文档的某个地方,不是吗? (7认同)
  • 在找到这个问题之前,我在这里查看了 http://msdn.microsoft.com/en-us/library/system.drawing.imaging.imageformat.jpeg.aspx。所以我本来希望有答案或其他一些文档的链接和答案。 (2认同)

lep*_*pie 5

IIRC,它是75%,但我不记得我在哪里读到这个.

  • 我用他的方法保存为75L,我用默认保存另一个.结果:`75L = 36.7 KB`和`default = 36.8 KB`.如果它不是75%那么它就像75.1%...... (3认同)