在C#中保存的JPG的质量
c#
image-processing
10
0

我制作了一个小型C#应用,以创建.jpg格式的图像。

pictureBox.Image.Save(name,ImageFormat.Jpeg);

图像创建成功。我输入了原始图片,并对其做了一些处理并保存。但是,此新图片的质量低于原始图片。

有什么方法可以设置所需的质量?

参考资料:
Stack Overflow
收藏
评论
共 7 个回答
高赞 时间 活跃

这是用于以特定质量另存为JPEG的更为紧凑的代码块:

var encoder = ImageCodecInfo.GetImageEncoders().First(c => c.FormatID == ImageFormat.Jpeg.Guid);
var encParams = new EncoderParameters() { Param = new[] { new EncoderParameter(Encoder.Quality, 90L) } };
image.Save(path, encoder, encParams);

或者,如果120个字符的宽行对您来说太长了:

var encoder = ImageCodecInfo.GetImageEncoders()
                            .First(c => c.FormatID == ImageFormat.Jpeg.Guid);
var encParams = new EncoderParameters(1);
encParams.Param[0] = new EncoderParameter(Encoder.Quality, 90L);
image.Save(path, encoder, encParams);

确保质量很long否则您将得到ArgumentException

收藏
评论

被接受的社区Wiki答案引用了Microsoft的示例。

但是,为了节省您的时间,我将其精简为

  • 包装成适当的方法
  • 已实现IDisposable 。我还没有看到在其他任何答案中using (...) {为了避免内存泄漏,最佳做法是处置所有实现IDisposable东西。

public static void SaveJpeg(string path, Bitmap image)
{
    SaveJpeg(path, image, 95L);
}
public static void SaveJpeg(string path, Bitmap image, long quality)
{
    using (EncoderParameters encoderParameters = new EncoderParameters(1))
    using (EncoderParameter encoderParameter = new EncoderParameter(Encoder.Quality, quality))
    {
        ImageCodecInfo codecInfo = ImageCodecInfo.GetImageDecoders().First(codec => codec.FormatID == ImageFormat.Jpeg.Guid);
        encoderParameters.Param[0] = encoderParameter;
        image.Save(path, codecInfo, encoderParameters);
    }
}
收藏
评论

如果使用的是.NET Compact Framework,则替代方法可能是使用PNG无损格式,即:

image.Save(filename, ImageFormat.Png);
收藏
评论

这是一个旧线程,但是我重写了Microsoft(按照Dustin Getz的回答),以使其更加有用-缩小GetEncoderInfo并在Image上进行扩展。无论如何,没有什么真正新的,但可能有用:

    /// <summary>
    /// Retrieves the Encoder Information for a given MimeType
    /// </summary>
    /// <param name="mimeType">String: Mimetype</param>
    /// <returns>ImageCodecInfo: Mime info or null if not found</returns>
    private static ImageCodecInfo GetEncoderInfo(String mimeType)
    {
        var encoders = ImageCodecInfo.GetImageEncoders();
        return encoders.FirstOrDefault( t => t.MimeType == mimeType );
    }

    /// <summary>
    /// Save an Image as a JPeg with a given compression
    ///  Note: Filename suffix will not affect mime type which will be Jpeg.
    /// </summary>
    /// <param name="image">Image: Image to save</param>
    /// <param name="fileName">String: File name to save the image as. Note: suffix will not affect mime type which will be Jpeg.</param>
    /// <param name="compression">Long: Value between 0 and 100.</param>
    private static void SaveJpegWithCompressionSetting(Image image, string fileName, long compression)
    {
        var eps = new EncoderParameters(1);
        eps.Param[0] = new EncoderParameter(Encoder.Quality, compression);
        var ici = GetEncoderInfo("image/jpeg");
        image.Save(fileName, ici, eps);
    }

    /// <summary>
    /// Save an Image as a JPeg with a given compression
    /// Note: Filename suffix will not affect mime type which will be Jpeg.
    /// </summary>
    /// <param name="image">Image: This image</param>
    /// <param name="fileName">String: File name to save the image as. Note: suffix will not affect mime type which will be Jpeg.</param>
    /// <param name="compression">Long: Value between 0 and 100.</param>
    public static void SaveJpegWithCompression(this Image image, string fileName, long compression)
    {
        SaveJpegWithCompressionSetting( image, fileName, compression );
    }
收藏
评论

使用无类型GDI +样式( https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms533845(v=vs.85).aspx )属性来设置JPEG质量看起来有些过分。

直接方法应如下所示:

FileStream stream = new FileStream("new.jpg", FileMode.Create);
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.QualityLevel = 100;   // "100" for maximum quality (largest file size).
encoder.Frames.Add(BitmapFrame.Create(image));
encoder.Save(stream);

参考: https : //msdn.microsoft.com/zh-cn/library/system.windows.media.imaging.jpegbitmapencoder.rotation(v= vs.110).aspx# Anchor_2

收藏
评论

下面的代码示例演示如何使用EncoderParameter构造函数创建EncoderParameter。要运行此示例,请粘贴代码并调用VaryQualityLevel方法。

本示例需要位于c:的名为TestPhoto.jpg的图像文件。

private void VaryQualityLevel()
{
    // Get a bitmap.
    Bitmap bmp1 = new Bitmap(@"c:\TestPhoto.jpg");
    ImageCodecInfo jgpEncoder = GetEncoder(ImageFormat.Jpeg);

    // Create an Encoder object based on the GUID
    // for the Quality parameter category.
    System.Drawing.Imaging.Encoder myEncoder =
        System.Drawing.Imaging.Encoder.Quality;

    // Create an EncoderParameters object.
    // An EncoderParameters object has an array of EncoderParameter
    // objects. In this case, there is only one
    // EncoderParameter object in the array.
    EncoderParameters myEncoderParameters = new EncoderParameters(1);

    EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 
        50L);
    myEncoderParameters.Param[0] = myEncoderParameter;
    bmp1.Save(@"c:\TestPhotoQualityFifty.jpg", jgpEncoder, 
        myEncoderParameters);

    myEncoderParameter = new EncoderParameter(myEncoder, 100L);
    myEncoderParameters.Param[0] = myEncoderParameter;
    bmp1.Save(@"c:\TestPhotoQualityHundred.jpg", jgpEncoder, 
        myEncoderParameters);

    // Save the bitmap as a JPG file with zero quality level compression.
    myEncoderParameter = new EncoderParameter(myEncoder, 0L);
    myEncoderParameters.Param[0] = myEncoderParameter;
    bmp1.Save(@"c:\TestPhotoQualityZero.jpg", jgpEncoder, 
        myEncoderParameters);

}

private ImageCodecInfo GetEncoder(ImageFormat format)
{
    ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
    foreach (ImageCodecInfo codec in codecs)
    {
        if (codec.FormatID == format.Guid)
        {
            return codec;
        }
    }
    return null;
}

参考: http : //msdn.microsoft.com/en-us/library/system.drawing.imaging.encoderparameter.aspx

收藏
评论

查看有关如何设置JPEG压缩级别的 MSDN文章。

您需要使用其他采用ImageEncoder及其参数的Save()重载。

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题