363 Stimmen

In GDI+, JPEG Image to MemoryStream ist ein allgemeiner Fehler aufgetreten

Dieser Fehler scheint im ganzen Web berüchtigt zu sein. So sehr, dass ich nicht in der Lage gewesen, eine Antwort auf mein Problem zu finden, da mein Szenario nicht passt. Eine Ausnahme wird ausgelöst, wenn ich das Bild in den Stream speichern.

Seltsamerweise funktioniert dies perfekt mit einem png, aber gibt den oben genannten Fehler mit jpg und gif, die ziemlich verwirrend ist.

Die meisten ähnlichen Probleme beziehen sich auf das Speichern von Bildern in Dateien ohne Berechtigungen. Ironischerweise ist die Lösung, einen Speicherstrom zu verwenden, wie ich es tue....

public static byte[] ConvertImageToByteArray(Image imageToConvert)
{
    using (var ms = new MemoryStream())
    {
        ImageFormat format;
        switch (imageToConvert.MimeType())
        {
            case "image/png":
                format = ImageFormat.Png;
                break;
            case "image/gif":
                format = ImageFormat.Gif;
                break;
            default:
                format = ImageFormat.Jpeg;
                break;
        }

        imageToConvert.Save(ms, format);
        return ms.ToArray();
    }
}

Mehr Details zur Ausnahme. Der Grund, warum dies so viele Probleme verursacht, ist das Fehlen einer Erklärung :(

System.Runtime.InteropServices.ExternalException was unhandled by user code
Message="A generic error occurred in GDI+."
Source="System.Drawing"
ErrorCode=-2147467259
StackTrace:
   at System.Drawing.Image.Save(Stream stream, ImageCodecInfo encoder, EncoderParameters    encoderParams)
   at System.Drawing.Image.Save(Stream stream, ImageFormat format)
   at Caldoo.Infrastructure.PhotoEditor.ConvertImageToByteArray(Image imageToConvert) in C:\Users\Ian\SVN\Caldoo\Caldoo.Coordinator\PhotoEditor.cs:line 139
   at Caldoo.Web.Controllers.PictureController.Croppable() in C:\Users\Ian\SVN\Caldoo\Caldoo.Web\Controllers\PictureController.cs:line 132
   at lambda_method(ExecutionScope , ControllerBase , Object[] )
   at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
   at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassa.<InvokeActionMethodWithFilters>b__7()
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
 InnerException: 

OK Dinge, die ich bisher ausprobiert habe.

  1. Klonen Sie das Bild und arbeiten Sie daran.
  2. Abrufen des Kodierers für diese MIME-Datei, die mit der Qualitätseinstellung jpeg übergeben wird.

222voto

madcapnmckay Punkte 15511

OK Ich scheine die Ursache nur durch schieres Glück gefunden zu haben und es ist nichts falsch mit dieser bestimmten Methode, es ist weiter hinten im Aufrufstapel.

Zuvor habe ich die Größe des Bildes geändert und als Teil dieser Methode gebe ich das geänderte Objekt wie folgt zurück. Ich habe zwei Aufrufe der obigen Methode und eine direkte Speicherung in einer Datei eingefügt.

// At this point the new bitmap has no MimeType
// Need to output to memory stream
using (var m = new MemoryStream())
{
       dst.Save(m, format);

       var img = Image.FromStream(m);

       //TEST
       img.Save("C:\\test.jpg");
       var bytes = PhotoEditor.ConvertImageToByteArray(img);

       return img;
 }

Es scheint, dass der Speicherstrom, auf dem das Objekt erstellt wurde hat die zum Zeitpunkt der Speicherung des Objekts geöffnet sein muss. Ich bin mir nicht sicher, warum das so ist. Kann mich jemand aufklären und mir sagen, wie ich dieses Problem umgehen kann?

Ich kehre nur von einem Stream zurück, weil ich nach der Verwendung des Größenänderungscodes ähnlich wie bei cette Die Zieldatei hat einen unbekannten Mime-Typ (img.RawFormat.Guid) und ich möchte, dass der Mime-Typ bei allen Bildobjekten korrekt ist, da es sonst schwierig ist, generischen Bearbeitungscode zu schreiben.

EDIT

Bei meiner anfänglichen Suche habe ich das nicht gefunden, aber hier ist die Antwort von Jon Skeet

148voto

Savindra Punkte 1431

Wenn Sie diese Fehlermeldung erhalten, kann ich sagen, dass Ihre Anwendung keine Schreibberechtigung für ein Verzeichnis hat.

Wenn Sie z. B. versuchen, das Bild aus dem Speicherstrom im Dateisystem zu speichern, kann dieser Fehler auftreten.

Wenn Sie XP verwenden, stellen Sie bitte sicher, dass Sie dem aspnet-Konto Schreibrechte für diesen Ordner erteilen.

Wenn Sie Windows Server (2003, 2008) oder Vista verwenden, stellen Sie sicher, dass Sie Schreibrechte für das Netzwerkdienstkonto hinzufügen.

Ich hoffe, es hilft jemandem.

64voto

Fred Punkte 1232

Ich füge auch diese Fehlerursache hinzu, in der Hoffnung, dass sie einem zukünftigen Internet-Reisenden hilft :)

GDI+ begrenzt die maximale Höhe eines Bildes auf 65500

Wir führen einige grundlegende Änderungen der Bildgröße durch, versuchen dabei aber, das Seitenverhältnis beizubehalten. Wir haben einen QA-Mitarbeiter, der in diesem Job etwas zu gut ist; er beschloss, dies mit einem EIN Pixel breiten Foto zu testen, das 480 Pixel hoch war. Als das Bild auf unsere Maße skaliert wurde, lag die Höhe bei über 68.000 Pixeln und unsere App explodierte mit A generic error occurred in GDI+ .

Sie können dies selbst mit einem Test überprüfen:

  int width = 480;
  var height = UInt16.MaxValue - 36; //succeeds at 65499, 65500
  try
  {
    while(true)
    {
      var image = new Bitmap(width, height);
      using(MemoryStream ms = new MemoryStream())
      {
        //error will throw from here
        image.Save(ms, ImageFormat.Jpeg);
      }
      height += 1;
    }
  }
  catch(Exception ex)
  {
    //explodes at 65501 with "A generic error occurred in GDI+."
  }

Schade, dass es kein freundliches .net gibt. ArgumentException die im Konstruktor von Bitmap .

40voto

Ivan Mesic Punkte 585

Dieser Artikel erklärt im Detail, was genau passiert: Abhängigkeiten von Bitmap- und Image-Konstruktoren

Kurz gesagt, für ein ganzes Leben eines Image konstruiert aus einer Strom darf der Strom nicht zerstört werden.

Also, statt

using (var strm = new ... )  {
    myImage = Image.FromStream(strm);
}

Versuchen Sie dies

Stream imageStream;
...

    imageStream = new ...;
    myImage = Image.FromStream(strm);

und schließen imageStream beim Schließen des Formulars oder der Webseite.

32voto

Kirk Broadhurst Punkte 26286

Sie erhalten diese Ausnahme auch, wenn Sie versuchen, in einem ungültigen Pfad zu speichern, oder wenn es ein Problem mit den Berechtigungen gibt.

Wenn Sie nicht 100%ig sicher sind, dass der Dateipfad verfügbar ist und die Berechtigungen korrekt sind, versuchen Sie, eine Textdatei zu schreiben. Dies dauert nur ein paar Sekunden, um auszuschließen, was eine sehr einfache Lösung wäre.

var img = System.Drawing.Image.FromStream(incomingStream);

// img.Save(path);
System.IO.File.WriteAllText(path, "Testing valid path & permissions.");

Und vergessen Sie nicht, Ihre Datei zu bereinigen.

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