14 Stimmen

.NET Speichern von jpeg in der gleichen Qualität wie beim Laden

Ich habe eine Kanonen-Digitalkamera und stelle sie so ein, dass sie Bilder mit superfeiner Qualität aufnimmt und eine .jpg-Datei mit einer Größe von 3 Megabyte ausgibt. Wenn ich sie so in ASP.NET lade (dies ist nützlich, um die dpi-Auflösung zu ändern oder sie zu beschneiden oder was auch immer)

imgPicture = Image.FromFile(Config.WorkDirectory + this.TempPhotoName);
bmpPicture = new Bitmap(imgPicture);

und dann speichere ich es wieder so:

bmpModified.Save(Config.WorkDirectory + this.TempPhotoName,System.Drawing.Imaging.ImageFormat.Jpeg);

Es gibt ein jpg aus, das nur etwa 700 KB groß ist. Das ist ein Qualitätsverlust.

Ich habe auch versucht, es auf diese Weise zu speichern:

bmpPicture.Save(Config.WorkDirectory + this.TempPhotoName, codecJpeg, encparams);

wobei codecJpeg für

ImageCodecInfo codecJpeg = this.getEncoderInfo("image/jpeg");

    private ImageCodecInfo getEncoderInfo(string mimeType)
    {
        // Get image codecs for all image formats
        ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();

        // Find the correct image codec
        for (int i = 0; i < codecs.Length; i++)
            if (codecs[i].MimeType == mimeType)
                return codecs[i];
        return null;
    }

und encparams:

EncoderParameters encparams = new EncoderParameters(1);
encparams.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 97L);

Auf diese Weise wird die Größe (und ich vermute, auch die Qualität) beibehalten, aber ich gebe die Qualität von Hand ein.

Ich möchte fragen:

Gibt es eine Möglichkeit, das Bild mit der gleichen Qualität zu speichern, wie es geladen wurde, ohne den Qualitätswert fest zu kodieren?

Ich danke Ihnen im Voraus

5voto

Jon Skeet Punkte 1325502

Es klingt also so, als wüssten Sie, wie man die Qualität einstellt, Sie müssen nur wissen, wie man abrufen. die Qualität des Originalbildes?

Ich vermute, dass Image.PropertyItems ist Ihr Freund, wenn die Qualität zunächst in den Metadaten liegt. (Ich weiß nicht, ob es bei JPEG-Encodern überhaupt eine Standardskala für die Qualität gibt).

EDIT: Ich habe gerade nachgesehen, und ein jpeg, das ich heruntergeladen habe, hatte keine Markierungen für die Qualität.

Eine Möglichkeit wäre, zu ermitteln, wie groß die Datei sein sollte, damit sie ungefähr die gleiche Qualität hat, und sie dann mehrmals zu speichern, wobei eine binäre Suche durchgeführt wird, um die beste Qualität zu ermitteln. Das ist mühsam, aber es könnte funktionieren.

Ich habe den leisen Verdacht, dass es ist nicht eine Möglichkeit, einfach die ursprüngliche Qualitätseinstellung beizubehalten, obwohl ich keine guten Gründe für diese Vermutung habe...

2 Stimmen

Das Setzen von PropertyItems und das erneute Speichern führen zu einem Qualitätsverlust, da das Bild neu kodiert wird. Lesen Sie hier mehr: stackoverflow.com/questions/1038206/

0 Stimmen

Ja, ich weiß, dass es neu kodiert wird - aber ich denke, es ist sinnvoll, mit ungefähr dem gleichen "Verlust" wie das Original neu zu kodieren, falls Sie das wünschen. Sie werden zwar immer noch Daten verlieren, aber wahrscheinlich keine große Menge. Beachten Sie auch, dass ich nicht über Einstellung PropertyItems - Ich sprach über Abrufen von um die ursprüngliche Qualität herauszufinden, obwohl dort offenbar nicht die entsprechenden Daten zu finden sind.

0 Stimmen

Nun gibt es propertyitem Element für die Abholung jpeg Qualität - PropertyTagJPEGQuality, aber es als private Tag für Adobe Photoshop angegeben, so dass ich nicht weiß, es ist von der Kamera gefüllt oder nicht. Auf jeden Fall gibt es ein wenig Sinn der Speicherung jpeg mit dem gleichen Wert jpeg Qualität, weil Qualitätsverlust wird es sein.

1voto

arbiter Punkte 9273

Lesen Sie hier, wie Sie ein Bild speichern können, ohne es neu zu kodieren: Gewusst wie: Neukodierung eines JPEG-Bildes mit Metadaten .

Allerdings, wenn Sie tun, Beschneiden oder eine andere Bildmanipulation es unmöglich, es ohne Qualitätsverlust zu tun (gut technisch ist es möglich, verlustfreie Ernte zu tun, wenn Sie mit Grenzen, die von 16 multiplizieren arbeiten, aber AFAIK ist es nicht mit Bibliotheken in .net verfügbar getan werden).

0voto

Egbert Nierop Punkte 1

Sie müssen die zusätzlichen Parameter verwenden, die GDI+ anweisen, das Farbschema zu erkennen.

Zum Beispiel:

using (var img = Image.FromStream(fileupload.InputStream, true,true))
{
    img.Save(fileOnDisk, ImageFormat.Jpeg);
}

using (var img = Image.FromFile("yourimage", true))
{
    img.Save(fileOnDisk, ImageFormat.Jpeg);
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X