Frage

Gibt es eine Möglichkeit, ein BMP-Bild in JPG/PNG zu konvertieren, ohne die Qualität in C# zu verlieren?Mit der Image-Klasse können wir BMP in JPG konvertieren, aber die Qualität des Ausgabebildes ist sehr schlecht.Können wir die gleiche Qualität erreichen wie ein Bild, das mit Photoshop in höchster Qualität in JPG konvertiert wurde?

War es hilfreich?

Lösung

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

Andere Tipps

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

Vorausgesetzt, BitmapExtensions von jestro sind großartig, ich habe sie verwendet.Ich möchte jedoch die korrigierte Version zeigen – funktioniert für die übergeordnete Image-Klasse, was meiner Meinung nach praktischer ist und eine Möglichkeit bietet, Qualität bereitzustellen:

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

Grundsätzlich können Sie nicht die gleiche Qualität beibehalten, da JPG (soweit mir bekannt ist) selbst bei höchstmöglichen Qualitätseinstellungen immer verlustbehaftet ist.

Wenn eine bitgenaue Qualität wirklich wichtig ist, sollten Sie die Verwendung von PNG in Betracht ziehen, das über einige verlustfreie Modi verfügt.

Ich möchte nur sagen, dass JPEG von Natur aus ein verlustbehaftetes Format ist.Selbst bei den höchsten Einstellungen wird es also zu einem gewissen Informationsverlust kommen, aber das hängt stark vom Bild ab. Aber PNG ist verlustfrei.

Du kannst es versuchen:

Bitmap.InterpolationMode = InterpolationMode.HighQualityBicubic;

Und

Bitmap.CompositingQuality = CompositingQuality.HighQuality;

Dadurch bleibt die Qualität ziemlich hoch, aber nicht die höchstmögliche.

Ich arbeite an einer Spesenabrechnungs-App und bin mit den Standardqualitätseinstellungen für JPG (und PNG) beim Speichern aus einem Bitmap-Objekt sehr zufrieden.

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

Ich verwende .NET 4.6 ... vielleicht hat sich die Qualität in nachfolgenden Framework-Versionen verbessert.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top