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.

0voto

Ε Г И І И О Punkte 9264

Für mich war die Image.Save(Stream, ImageCodecInfo, EncoderParameters) und das war offenbar die Ursache für die berüchtigte A generic error occurred in GDI+ Fehler.

Ich habe versucht, die EncoderParameter um die Jpegs in 100%iger Qualität zu speichern. Dies funktionierte auf "meinem Rechner" (puh!) perfekt, nicht aber in der Produktion.

Als ich die Image.Save(Stream, ImageFormat) stattdessen ist der Fehler verschwunden! Wie ein Idiot habe ich also weiterhin letztere verwendet, obwohl sie in der Standardqualität gespeichert werden, die vermutlich nur 50 % beträgt.

Ich hoffe, diese Informationen helfen jemandem.

0voto

Soon Khai Punkte 594

Meine Konsolenanwendung erhielt die gleiche Fehlermeldung: "Ein allgemeiner Fehler ist in GDI+ aufgetreten". Der Fehler trat in der Zeile newImage.Save wie der folgende Code zeigt.

for (int i = 1; i <= 1000; i++)
{
   Image newImage = Image.FromFile(@"Sample.tif");
   //...some logic here
   newImage.Save(i + ".tif", , ImageFormat.Tiff);
}

Das Programm gab einen Fehler zurück, wenn die RAM-Auslastung etwa 4 GB beträgt, und schaffte es, das Problem durch Ändern der Programmziel a x64 in den Projekteigenschaften.

0voto

Ivan Smyrnov Punkte 329

Ich habe eine seltsame Lösung für dieses Problem. Ich wurde während der Codierung darauf aufmerksam gemacht. Ich dachte, dass Bitmap ist struct und wrap um es mit Methode. In meiner Vorstellung wird Bitmap innerhalb der Methode kopiert und aus der Methode zurückgegeben. Aber später habe ich überprüft, dass es eine Klasse ist, und ich habe keine Ahnung, warum es mir geholfen hat, aber es funktioniert! Vielleicht hat ja jemand Zeit und Spaß daran, sich den IL-Code davon anzusehen ;) Ich bin mir nicht sicher, ob es funktioniert, weil diese Methode statisch innerhalb einer statischen Methode ist, ich weiß es nicht.

        public SomeClass
        {
            public byte[] _screenShotByte;
            public Bitmap _screenShotByte;
            public Bitmap ScreenShot 
            { 
                get
                {
                    if (_screenShot == null)
                    {
                        _screenShotByte = ScreenShot();
                        using (var ms = new MemoryStream(_screenShotByte))
                        {
                            _screenShot = (Bitmap)Image.FromStream(ms);
                        }

                        ImageUtils.GetBitmap(_screenShot).Save(Path.Combine(AppDomain.CurrentDomain.BaseDirectory) ,$"{DateTime.Now.ToFileTimeUtc()}.png"));

                    }
                    return ImageUtils.GetBitmap(_screenShot);
                }
            }
            public byte[] ScreenShot()
            {
                ///....return byte array for image in my case implementedd like selenium screen shot 
            }
        }
        public static ImageUtils
        {
            public static Bitmap GetBitmap(Bitmap image)
            {
                return Bitmap;
            }
        }

p.s. Es ist nicht Trolling diese Lösung löste Problem der Verwendung von Bitmap nach dem Speichern in einem anderen Orten zu halten.

0voto

Klaus Punkte 2231

Das Problem ist auch bei mir aufgetreten. Das Problem war darauf zurückzuführen, dass der Ladestrom entsorgt wurde. Aber ich habe ihn nicht entsorgt, er befand sich im .Net-Framework. Alles, was ich tun musste, war zu verwenden:

image_instance = Image.FromFile(file_name);

anstelle von

image_instance.Load(file_name);

image_instance ist vom Typ System.Windows.Forms.PictureBox! Die Funktion Load() der PictureBox entsorgt den Stream, aus dem das Bild geladen wurde, und das wusste ich nicht.

0voto

Clinton Ward Punkte 2363

Wenn Sie so weit gekommen sind, können Sie Folgendes versuchen.

Ändern Sie Ihre Anwendungspool-Identitätseinstellung von ApplicationPoolIdentity a LocalSystem um zu überprüfen, ob es sich um ein Berechtigungsproblem handelt.

Verwenden Sie diese Einstellung jedoch nicht dauerhaft, da sie ein Sicherheitsrisiko darstellt; verwenden Sie sie nur zur Diagnose

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