Cmp中的Bmp到jpg/png

Ram*_*oni 53 c# image-manipulation

有没有办法将bmp图像转换为jpg/png而不会失去C#的质量?使用Image类我们可以将bmp转换为jpg,但输出图像的质量非常差.我们可以使用最高质量的photoshop获得与转换为jpg的图像一样好的质量水平吗?

aku*_*aku 55

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
Run Code Online (Sandbox Code Playgroud)

  • 这里不应该有一些 _using_ 语句吗?我注意到 EncoderParameter 是 IDisposable,但我对一次性模式的掌握程度还不够,无法确定需要它们。 (2认同)
  • 是的,应该有一些using语句。上面的代码是可以做什么的示例,而不是应该使用什么。 (2认同)

jes*_*tro 33

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 甚至更短的`返回ImageCodecInfo.GetImageEncoders().FirstOrDefault(x => x.FormatID == ImageFormat.Jpeg.Guid);`. (2认同)

net*_*rog 11

由jestro提供的BitmapExtensions很棒,我用它们.但是想要显示更正的版本 - 适用于Image父类,这比我想象的更方便,并提供了一种提供质量的方法:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)