Bmp to jpg/png in C#

陌路散爱 提交于 2019-11-27 00:40:11
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
jestro
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;
    }
}

Provided BitmapExtensions by jestro are great, I used them. However would like to show the corrected version - works for Image parent class which is more convenient as I think and provides a way to supply quality:

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);
    }
}

Fundamentally you won't be able to keep the same quality because jpg is (so far as I'm aware) always lossy even with the highest possible quality settings.

If bit-accurate quality is really important, consider using png, which has some modes which are lossless.

Just want to say that JPEG is by nature a lossy format. So in thoery even at the highest settings you are going to have some information loss, but it depends a lot on the image.But png is lossless.

You can try:

Bitmap.InterpolationMode = InterpolationMode.HighQualityBicubic;

and

Bitmap.CompositingQuality = CompositingQuality.HighQuality;

Which does keep the quality fairly high, but not the highest possible.

I am working on an expense report app, and I am really pleased with the default quality settings for JPG (and PNG) when saving from a Bitmap object.

https://msdn.microsoft.com/en-us/library/9t4syfhh%28v=vs.110%29.aspx

Bitmap finalBitmap = ....; //from disk or whatever
finalBitmap.Save(xpsFileName + ".final.jpg", ImageFormat.Jpeg);
finalBitmap.Save(xpsFileName + ".final.png", ImageFormat.Png);

I'm on .NET 4.6...perhaps the quality has improved in subsequent framework releases.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!