[c#] Image.Save (..) genera un'eccezione GDI + perché il flusso di memoria è chiuso



Answers

Si è verificato un errore generico in GDI +. Può anche derivare da un percorso di salvataggio errato ! Mi ci sono voluto mezza giornata per accorgermene. Quindi assicurati di aver ricontrollato anche il percorso per salvare l'immagine.

Question

Ho alcuni dati binari che voglio salvare come immagine. Quando provo a salvare l'immagine, genera un'eccezione se il flusso di memoria utilizzato per creare l'immagine, è stato chiuso prima del salvataggio. La ragione per cui lo faccio è perché sto creando dinamicamente le immagini e come tale .. ho bisogno di usare un flusso di memoria.

questo è il codice:

[TestMethod]
public void TestMethod1()
{
    // Grab the binary data.
    byte[] data = File.ReadAllBytes("Chick.jpg");

    // Read in the data but do not close, before using the stream.
    Stream originalBinaryDataStream = new MemoryStream(data);
    Bitmap image = new Bitmap(originalBinaryDataStream);
    image.Save(@"c:\test.jpg");
    originalBinaryDataStream.Dispose();

    // Now lets use a nice dispose, etc...
    Bitmap2 image2;
    using (Stream originalBinaryDataStream2 = new MemoryStream(data))
    {
        image2 = new Bitmap(originalBinaryDataStream2);
    }

    image2.Save(@"C:\temp\pewpew.jpg"); // This throws the GDI+ exception.
}

Qualcuno ha qualche suggerimento su come posso salvare un'immagine con lo stream chiuso? Non posso fare affidamento sugli sviluppatori per ricordare di chiudere lo stream dopo che l'immagine è stata salvata. In effetti, lo sviluppatore non avrebbe IDEA che l'immagine sia stata generata usando un flusso di memoria (perché accade in qualche altro codice, altrove).

Sono veramente confuso :(




Una strana soluzione che ha reso il mio codice funzionante. Apri l'immagine in vernice e salvala come un nuovo file con lo stesso formato (.jpg). Ora prova con questo nuovo file e funziona. Ti spiega chiaramente che il file potrebbe essere danneggiato in qualche modo. Questo può aiutare solo se il tuo codice ha risolto ogni altro errore




Per me il codice sottostante si è bloccato con A generic error occurred in GDI+ sulla riga che salva su MemoryStream . Il codice era in esecuzione su un server Web e l'ho risolto arrestando e avviando il pool di applicazioni che stava eseguendo il sito.

Deve essere stato qualche errore interno in GDI +

    private static string GetThumbnailImageAsBase64String(string path)
    {
        if (path == null || !File.Exists(path))
        {
            var log = ContainerResolver.Container.GetInstance<ILog>();
            log.Info($"No file was found at path: {path}");
            return null;
        }

        var width = LibraryItemFileSettings.Instance.ThumbnailImageWidth;

        using (var image = Image.FromFile(path))
        {
            using (var thumbnail = image.GetThumbnailImage(width, width * image.Height / image.Width, null, IntPtr.Zero))
            {
                using (var memoryStream = new MemoryStream())
                {
                    thumbnail.Save(memoryStream, ImageFormat.Png); // <= crash here 
                    var bytes = new byte[memoryStream.Length];
                    memoryStream.Position = 0;
                    memoryStream.Read(bytes, 0, bytes.Length);
                    return Convert.ToBase64String(bytes, 0, bytes.Length);
                }
            }
        }
    }



Questo errore mi è venuto in mente quando stavo provando da Citrix. La cartella immagine è stata impostata su C: \ nel server, per il quale non ho privilegi. Una volta che la cartella immagine è stata spostata su un'unità condivisa, l'errore era sparito.




Si è verificato un errore generico in GDI +. Può verificarsi a causa di problemi di memorizzazione delle immagini, ho ricevuto questo errore perché il percorso di archiviazione è troppo lungo, l'ho risolto memorizzando l'immagine in un percorso più breve e spostandola nella posizione corretta con tecniche di gestione del percorso lunghe.




Copia la bitmap. Devi mantenere lo stream aperto per tutta la durata della bitmap.

Quando si disegna un'immagine: System.Runtime.InteropServices.ExternalException: si è verificato un errore generico in GDI

    public static Image ToImage(this byte[] bytes)
    {
        using (var stream = new MemoryStream(bytes))
        using (var image = Image.FromStream(stream, false, true))
        {
            return new Bitmap(image);
        }
    }

    [Test]
    public void ShouldCreateImageThatCanBeSavedWithoutOpenStream()
    {
        var imageBytes = File.ReadAllBytes("bitmap.bmp");

        var image = imageBytes.ToImage();

        image.Save("output.bmp");
    }



Links