Frage

Ich habe gerade eine echte Überraschung, als ich eine jpg-Datei geladen und drehte mich um und rettete sie mit einer Qualität von 100 und die Größe war fast das Original 4x. Um weiter zu untersuchen, ich offen und gespeichert, ohne dass die Qualität und die Dateigröße explizit Einstellung war genau das gleiche. Ich dachte, dies war, weil sich nichts geändert, so dass es nur ist exakt die gleichen Bits Schreiben in eine Datei sichern. Um diese Annahme zu testen, zog ich eine dicke, fette Linie diagonal über das Bild und gespeichert wieder ohne Qualitätseinstellung (dieses Mal erwartete ich die Datei bis zu springen, weil es wäre „dirty“), aber es verringert ~ 10Kb!

An diesem Punkt verstehe ich wirklich nicht, was passiert, wenn ich einfach Image.Save () aufrufen, w / out eine Komprimierungsqualität festlegen. Wie ist die Dateigröße so nah (nachdem das Bild geändert wird) auf die Originalgröße, wenn keine Qualität noch gesetzt ist, wenn ich die Qualität auf 100 gesetzt (im Grunde keine Kompression) die Dateigröße mehrere Male größer als das Original ist?

Ich habe die Dokumentation auf Image.Save () gelesen und es fehlt jedes Detail über das, was hinter den Kulissen geschieht. Ich habe alle Richtungen gegoogelt ich denken kann, aber ich kann keine weiteren Informationen, die erklären würde, was ich sehe. Ich habe seit 31 Stunden arbeiten gerade so vielleicht etwas offensichtlich fehlt mir; 0)

All dies hat gekommen, während ich einige Bibliothek Methoden implementieren Bilder in einer Datenbank zu speichern. Ich habe unsere „Saveimage“ Methode überlastet explizit zu erlauben, eine Qualitätseinstellung und während meiner Tests ich über die ungerade kam (für mich) Ergebnisse oben erläutert. Jedes Licht, das Sie vergießen wird geschätzt.

Hier einige Code, wird zeigen, was ich erlebe:

string filename = @"C:\temp\image testing\hh.jpg";
string destPath = @"C:\temp\image testing\";

using(Image image = Image.FromFile(filename))
{
    ImageCodecInfo codecInfo = ImageUtils.GetEncoderInfo(ImageFormat.Jpeg);

    //  Set the quality
    EncoderParameters parameters = new EncoderParameters(1);

    // Quality: 10
    parameters.Param[0] = new EncoderParameter(
        System.Drawing.Imaging.Encoder.Quality, 10L);
    image.Save(destPath + "10.jpg", codecInfo, parameters);

    // Quality: 75
    parameters.Param[0] = new EncoderParameter(
        System.Drawing.Imaging.Encoder.Quality, 75L);
    image.Save(destPath + "75.jpg", codecInfo, parameters);

    // Quality: 100
    parameters.Param[0] = new EncoderParameter(
        System.Drawing.Imaging.Encoder.Quality, 100L);
    image.Save(destPath + "100.jpg", codecInfo, parameters);

    //  default
    image.Save(destPath + "default.jpg", ImageFormat.Jpeg);

    //  Big line across image
    using (Graphics g = Graphics.FromImage(image))
    {
        using(Pen pen = new Pen(Color.Red, 50F))
        {
            g.DrawLine(pen, 0, 0, image.Width, image.Height);
        }
    }

    image.Save(destPath + "big red line.jpg", ImageFormat.Jpeg);
}

public static ImageCodecInfo GetEncoderInfo(ImageFormat format)
{
    return ImageCodecInfo.GetImageEncoders().ToList().Find(delegate(ImageCodecInfo codec)
    {
        return codec.FormatID == format.Guid;
    });
}
War es hilfreich?

Lösung

Mit Reflektor, es stellt sich heraus Image.Save() läuft darauf hinaus, die GDI + Funktion nach unten GdipSaveImageToFile , mit dem encoderParams NULL. Also habe ich die Frage denken, was der JPEG-Encoder macht, wenn es eine Null-encoderParams bekommt. 75% wurde hier vorgeschlagen, aber ich kann keine feste Referenz finden.

Bearbeiten Sie könnten wahrscheinlich für sich selbst herausfinden, indem Sie Ihr Programm über Qualitätswerte von 1..100 laufen und sie mit dem jpg mit der Standard-Qualität gespeichert zu vergleichen (mit, sagen wir, fc.exe / B)

Andere Tipps

IIRC ist es 75%, aber ich nicht erinnern, wo ich diese Zeilen lesen.

Ich weiß nicht viel über die Image.Save Methode, aber ich kann Ihnen sagen, dass das Fett Zeile hinzufügen logicly die Größe des JPG-Bildes reduzieren würde. Dies ist auf die Art und Weise ein jpg gespeichert (und codiert).

Die dicke schwarze Linie sorgt für eine sehr einfache und kleinere Codierung (Wenn ich mich richtig erinnere, ist dies relevent meist nach der diskreten Cosinus-Transformation), so kann das modifizierte Bild weniger Daten (Bytes) unter Verwendung gespeichert werden.

jpg Codierung Schritte

Im Hinblick auf die Änderungen in der Größe (ohne die zusätzliche Linie), ich bin nicht sicher, ob das Bild, das Sie wieder geöffnet und resaved

Um weiter zu untersuchen, ich offen und gespeichert, ohne explizit Einstellung die Qualität und die Dateigröße genau das gleiche war

Wenn Sie das alte (ursprüngliche normale Größe) Bild geöffnet und wieder gespeichert es, dann vielleicht die Standard-Kompression und die ursprüngliche Bildkompression ist die gleiche. Wenn Sie das neue (4X größer) Bild geöffnet und wieder gespeichert es, dann vielleicht die Standard-Komprimierung für die Save-Methode wird aus dem Bild abgeleitet (wie es war, wenn geladen).

Noch einmal, ich weiß nicht, die Save-Methode, so dass ich nur Ideen zu werfen (vielleicht werden sie Ihnen eine Blei).

Wenn Sie ein Bild als JPEG-Datei mit einem Qualitätsniveau speichern <100%, Sie Artefakte in die gespeicherte Bild-off einführen, die ein Nebeneffekt des Kompressionsprozesses ist. Aus diesem Grund erneut Speichern des Bildes bei 100% tatsächlich die Größe der Datei über die ursprüngliche Vergrößern -. Ironischerweise gibt es mehr Informationen in der Bitmap

Dies ist auch, warum sollten Sie immer versuchen, in einem nicht-verlustbehaftetes Format (wie PNG) zu speichern, wenn Sie irgendwelche Änderungen an Dateien zu tun beabsichtigen danach, sonst werden Sie die Qualität der Ausgabe durch mehrere verlustbehaftete beeinflussen werden Transformationen.

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