Question

Existe-t-il un moyen de convertir une image bmp en jpg/png sans perdre la qualité en C# ?En utilisant la classe Image, nous pouvons convertir bmp en jpg mais la qualité de l'image de sortie est très mauvaise.Pouvons-nous obtenir un niveau de qualité aussi bon qu'une image convertie en jpg à l'aide de Photoshop avec la plus haute qualité ?

Était-ce utile?

La solution

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

Autres conseils

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

Les BitmapExtensions fournies par jestro sont excellentes, je les ai utilisées.Cependant, j'aimerais montrer la version corrigée - fonctionne pour la classe parent Image, ce qui est plus pratique à mon avis et fournit un moyen de fournir de la qualité :

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

Fondamentalement, vous ne pourrez pas conserver la même qualité car jpg est (pour autant que je sache) toujours avec perte, même avec les paramètres de qualité les plus élevés possibles.

Si la qualité au bit près est vraiment importante, envisagez d'utiliser png, qui propose certains modes sans perte.

Je veux juste dire que JPEG est par nature un format avec perte.Donc, en théorie, même avec les paramètres les plus élevés, vous allez avoir une certaine perte d'informations, mais cela dépend beaucoup de l'image. Mais le png est sans perte.

Tu peux essayer:

Bitmap.InterpolationMode = InterpolationMode.HighQualityBicubic;

et

Bitmap.CompositingQuality = CompositingQuality.HighQuality;

Ce qui maintient la qualité assez élevée, mais pas la plus élevée possible.

Je travaille sur une application de notes de frais et je suis vraiment satisfait des paramètres de qualité par défaut pour JPG (et PNG) lors de l'enregistrement à partir d'un objet Bitmap.

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

Je suis sur .NET 4.6... peut-être que la qualité s'est améliorée dans les versions ultérieures du framework.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top