webentwicklung-frage-antwort-db.com.de

Wie finde ich den Grund für den generischen GDI + -Fehler beim Speichern eines Bildes?

Mit einem Code, der beim Laden und Speichern von Bildern schon seit Ewigkeiten funktioniert, habe ich festgestellt, dass ich ein einziges Bild habe , das diesen Code umbricht:

const string i1Path = @"c:\my\i1.jpg";
const string i2Path = @"c:\my\i2.jpg";

var i = Image.FromFile(i1Path);
i.Save(i2Path, ImageFormat.Jpeg);

Die Ausnahme ist:

System.Runtime.InteropServices.ExternalException ist aufgetreten

In GDI + ist ein allgemeiner Fehler aufgetreten.

at System.Drawing.Image.Save (String-Dateiname, ImageCodecInfo-Encoder, EncoderParameters encoderParams)
bei System.Drawing.Image.Save (String-Dateiname, ImageFormat-Format)
beim ...

Soweit ich sehen kann, hat das Bild nichts Besonderes. Es ist ungefähr 250 Pixel groß und kann z. Windows Image Viewer oder Paint.NET:

enter image description here

(Da das obige Bild nach dem Hochladen in Stack Overflow nicht mehr den Fehler erzeugt, habe ich das Originalbild hier )

Ich habe festgestellt, dass beim Aufrufen der Save -Methode die Ziel-Image-Datei mit null Bytes erstellt wird.

Ich weiß wirklich nicht, was den Fehler verursacht.

Meine Fragen:

  • Können Sie sich etwas Besonderes vorstellen, das .NET daran hindert, das Bild zu speichern?
  • Gibt es eine Möglichkeit (neben der Panik), diese Art von Fehlern einzugrenzen?
29
Uwe Keim

Obwohl ich immer noch nicht herausgefunden habe, warum genau der Fehler beim Speichern des Bildes aufgetreten ist, habe ich eine Problemumgehung gefunden:

const string i1Path = @"c:\my\i1.jpg";
const string i2Path = @"c:\my\i2.jpg";

var i = Image.FromFile(i1Path);

var i2 = new Bitmap(i);
i2.Save(i2Path, ImageFormat.Jpeg);

Das heißt Wenn Sie das Bild intern in eine Bitmap - Instanz kopieren und dieses Bild anstelle des Originalbilds speichern, verschwindet der Fehler.

Ich gehe davon aus, dass durch das Kopieren die fehlerhaften Teile, die dazu geführt haben, dass der ursprüngliche Save -Aufruf fehlgeschlagen ist, entfernt und/oder normalisiert werden, sodass der Speichervorgang erfolgreich ist.

saved image i2.jpg

Interessanterweise hat das so gespeicherte Bild eine kleinere Datei auf der Festplatte (16 kB) als die ursprüngliche Quelle (26 kB).

39
Uwe Keim

Stellen Sie zunächst sicher, dass der gewünschte Ordner Lese-/Schreibrechte hat. Das Ändern der Berechtigungen löste dieses Problem für mich.

15

Lösung ist hier, müssen Sie Bildobjekt entsorgen, um den Speicher auf dem Server freizugeben. Versuchen Sie es mit der Anweisung using. Stellen Sie sicher, dass auch das Zielverzeichnis auf dem Server vorhanden ist.

7
Azarsa

Der Grund kann sein, dass das Bild träge geladen wird und der Ladevorgang noch nicht abgeschlossen ist, wenn Sie versuchen, es zu speichern.

Das Folgende, was in diesem Blog-Beitrag gesagt wird (vorausgesetzt, Sie sind Deutsch von dem Bild, das Sie in Ihrer Frage verlinkt haben), bietet eine mögliche Lösung. Auch diese SO Frage akzeptierte Antwort zeigt an, dass die Bilddatei, in der Sie speichern möchten, gesperrt ist.

[~ # ~] edit [~ # ~]
Für Ulysses Alves aus dem verknüpften Blogeintrag: Wenn Sie ein Bild mit Image.FromFile() laden, bleibt es gesperrt, bis es entsorgt wird. Dies verhindert Aufrufe von Save().

pictureBox1.Image = Image.FromFile("C:\\test\\test1.jpg");
pictureBox1.Image.Save("C:\\test\\test2.jpg");

Der obige Code löst einen Fehler aus.

Damit es funktioniert, müssen Sie das Bild kopieren. Der folgende Code funktioniert:

pictureBox1.Image = Image.FromFile("C:\\test\\test1.jpg");
Image copy = pictureBox1.Image;
copy.Save("C:\\test\\test2.jpg")
5

Ich habe diese Frage gefunden, weil ich auch auf einen ähnlichen Fehler gestoßen bin und die Datei tatsächlich mit der Länge Null erstellt (Wenn Sie keine Datei sehen, überprüfen Sie zuerst die Berechtigungen zum Schreiben in einen Ordner, wie andere Antworten vorschlagen) . Obwohl mein Code etwas anders war (ich benutze stream, um das Bild aus dem Speicher zu lesen, nicht aus der Datei), denke ich, dass meine Antwort für alle hilfreich sein kann, die mit ähnlichen Problemen konfrontiert sind.

Es sieht möglicherweise nicht intuitiv aus, aber Sie können den Speicher nicht wirklich löschen, bis Sie mit dem Bild fertig sind.

NICHT ARBEITEND:

Image patternImage;

using (var ms = new MemoryStream(patternBytes)) {
    patternImage = new Bitmap(ms);
}

patternImage.Save(patternFile, ImageFormat.Jpeg);

Entsorgen Sie den Stream erst, wenn Sie mit dem Bild fertig sind.

FUNKTIONIERT :

using (var ms = new MemoryStream(patternBytes)) {
    patternImage = new Bitmap(ms);
    patternImage.Save(patternFile, ImageFormat.Jpeg);
}

Was ist irreführend:

  • Die Fehlermeldung sagt Ihnen eigentlich nichts
  • Sie können die Bildeigenschaften wie Breite und Höhe anzeigen, aber nicht speichern
3
Mike Keskinov

meine Lösung bestand darin, temporären Inhalt (File.WriteAllText) kurz vor dem Speichern der Datei zu schreiben

Hier ist der Code:

var i = Image.FromFile(i1Path);
File.WriteAllText(i2Path, "empty");  // <---- magic goes here
i.Save(i2Path, ImageFormat.Jpeg);

Bitte versuchen Sie es und lassen Sie es mich wissen

3
mr.baby123

Im Programm öffnen

const string i1Path = @"c:\my\i1.jpg";

const string i2Path = @"c:\my\i2.jpg";

var i = Image.FromFile(i1Path);

i.Save(i2Path, ImageFormat.Jpeg);

i.Dispose();
0
Konstant