关于图像处理:在C#中将Bmp转换为jpg / png

关于图像处理:在C#中将Bmp转换为jpg / png

Bmp to jpg/png in C#

有什么方法可以将bmp图像转换为jpg / png而不损失C#的质量吗?使用Image类,我们可以将bmp转换为jpg,但是输出图像的质量很差。我们能否获得与使用质量最高的Photoshop转换为jpg的图像一样好的质量等级?


1
2
3
4
5
6
7
var qualityEncoder = Encoder.Quality;
var quality = (long)<desired quality>;
var ratio = new EncoderParameter(qualityEncoder, quality );
var codecParams = new EncoderParameters(1);
codecParams.Param[0] = ratio;
var jpegCodecInfo = <one of the codec infos from ImageCodecInfo.GetImageEncoders() with mime type ="image/jpeg">;
bmp.Save(fileName, jpegCodecInfo, codecParams); // Save to JPG

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public static class BitmapExtensions
{
    public static void SaveJPG100(this Bitmap bmp, string filename)
    {            
        EncoderParameters encoderParameters = new EncoderParameters(1);
        encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
        bmp.Save(filename, GetEncoder(ImageFormat.Jpeg), encoderParameters);
    }

    public static void SaveJPG100(this Bitmap bmp, Stream stream)
    {
        EncoderParameters encoderParameters = new EncoderParameters(1);
        encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
        bmp.Save(stream, GetEncoder(ImageFormat.Jpeg), encoderParameters);
    }

    public static ImageCodecInfo GetEncoder(ImageFormat format)
    {
        ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();

        foreach (ImageCodecInfo codec in codecs)
        {
            if (codec.FormatID == format.Guid)
            {
                return codec;
            }
        }

        return null;
    }
}

jestro提供的BitmapExtensions很棒,我使用了它们。但是,我想显示更正的版本-适用于Image父类,这在我看来更为方便,并提供了一种提供质量的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static class ImageExtensions
{
    public static void SaveJpeg(this Image img, string filePath, long quality)
    {
        var encoderParameters = new EncoderParameters(1);
        encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, quality);
        img.Save(filePath, GetEncoder(ImageFormat.Jpeg), encoderParameters);
    }

    public static void SaveJpeg(this Image img, Stream stream, long quality)
    {
        var encoderParameters = new EncoderParameters(1);
        encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, quality);
        img.Save(stream, GetEncoder(ImageFormat.Jpeg), encoderParameters);
    }

    static ImageCodecInfo GetEncoder(ImageFormat format)
    {
        ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
        return codecs.Single(codec => codec.FormatID == format.Guid);
    }
}

只想说JPEG本质上是一种有损格式。因此,即使在最高设置下,您也会丢失一些信息,但这在很大程度上取决于图像。但是png是无损的。


从根本上讲,您将无法保持相同的质量,因为jpg(据我所知)即使在可能的最高质量设置下也总是有损的。

如果精确到位的质量真的很重要,请考虑使用png,它具有一些无损的模式。


我正在开发一项费用报告应用程序,从位图对象保存时,我对JPG(和PNG)的默认质量设置感到非常满意。

https://msdn.microsoft.com/zh-cn/library/9t4syfhh(v = vs.110).aspx

1
2
3
Bitmap finalBitmap = ....; //from disk or whatever
finalBitmap.Save(xpsFileName +".final.webp", ImageFormat.Jpeg);
finalBitmap.Save(xpsFileName +".final.webp", ImageFormat.Png);

我在.NET 4.6上...也许在后续框架版本中质量有所提高。


您可以尝试:

1
Bitmap.InterpolationMode = InterpolationMode.HighQualityBicubic;

1
Bitmap.CompositingQuality = CompositingQuality.HighQuality;

确实可以保证较高的质量,但不能保持最高的质量。


推荐阅读