tengo algunos datos binarios que quiero guardar como una imagen. Cuando intento guardar la imagen, se produce una excepción si la secuencia de memoria se utiliza para crear la imagen, fue cerrado antes de guardar. La razón por la que hago esto es porque estoy crear dinámicamente las imágenes y, como tal .. necesito utilizar una secuencia de memoria.

este es el código:

[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.
}

¿Alguien tiene alguna sugerencia de cómo podría guardar una imagen con el flujo cerrado? No puedo confiar en los desarrolladores para recordar a cerrar la secuencia después de que la imagen se guarda. De hecho, el desarrollador NO tiene IDEA de que la imagen fue generada usando una secuencia de memoria (porque ocurre en algunos otros códigos, otros).

Estoy realmente confundido 🙁

  • Por favor, no utilice imágenes de código como este, hace que sea más difícil para las personas que copiar el código en un intento de cambiar a un estado de trabajo. Voy a editar para que se utilice la sintaxis de markdown.
  • Tengo este comentario de @HansPassant en otro question. Obtendrás esta excepción cuando el códec tiene problemas para escribir en el archivo. Una buena depuración de instrucción para agregar es el Sistema.IO.Archivo.WriteAllText(ruta, «prueba») antes de Guardar() la llamada, se verifica la capacidad básica para crear el archivo. Ahora vamos a obtener una buena excepción que le dice lo que hizo mal.
  • Usted debe image2.Guardar dentro de using bloque. Creo que el originalBinaryDataStream2 se eliminan automáticamente al final de la uso. Y que lanzaría la excepción.
InformationsquelleAutor Pure.Krome | 2008-12-03

14 Comentarios

  1. 160

    Ya que es un MemoryStream, usted realmente no necesidad para cerrar la secuencia – nada malo va a pasar si no lo hace, aunque, obviamente, es una buena práctica para disponer cualquier cosa que se desechables de todos modos. (Ver esta pregunta para más información sobre esto).

    Sin embargo, usted debe se deseche el mapa de bits – y que va a cerrar la secuencia para usted. Básicamente, una vez que usted dé el constructor de mapa de bits de un arroyo, que es «dueño» de la corriente, y usted no debe cerrar. Como la documentación para que el constructor decir:

    Debe mantener el flujo de abrir para el
    toda la vida de el mapa de bits.

    Yo no puedo encontrar ninguna documentación prometedor para cerrar la secuencia cuando se deshaga el mapa de bits, pero usted debería ser capaz de verificar que con bastante facilidad.

    • impresionante! esa es una gran respuesta de Jon. Tiene perfecto sentido (y me perdí el poco acerca de la secuencia en la documentación). Dos Pulgares Para Arriba! Voy a informar de cuando me he dado una oportunidad 🙂
    • Eso es muy extraño. Me parece recordar que la Imagen tiene algo de especial carcasa alrededor de las secuencias de memoria, aunque puedo estar equivocado, pero que podría explicarlo.
    • Cualquier comentario de cómo ir sobre esto, si queremos obedecer la regla CA2000? (msdn.microsoft.com/en-us/library/ms182289.aspx)
    • Simplemente no aplicable – usted ha transferido la propiedad del recurso, básicamente. Lo más cercano que podía venir sería crear un «NonClosingStream» contenedor que ignora el Disponer de la llamada. Creo que puede tener uno en MiscUtil – no estoy seguro…
    • Gracias por la info @Jon. Para mí, por alguna extraña razón estaba trabajando incluso con el dispose() en el local del entorno dev, pero no trabajan en la producción.
  2. 87

    Un error genérico que se produjo en GDI+.
    También puede resultar de incorrecto ruta para guardar!
    Me tomó la mitad de un día a cuenta de que.
    Así que asegúrese de que usted tiene registrado el doble de la ruta para guardar la imagen.

    • Me alegro de esto, que mi camino era C\Users\mason\Desktop\pic.png. Falta de colon! Me habría pasado para siempre antes de que me di cuenta de que.
    • Usted salvó mi día!! Probé varias cosas y tu comentario ponga luz sobre mi problema!! Un millón de gracias!!!
    • Incorrecta también significa que una carpeta de la que desea guardar la imagen no existe.
    • No puedo agradecerles lo suficiente. Mi carpeta no existía en el disco así el error. Gracias.
  3. 14

    Tal vez vale la pena mencionar que si el C:\Temp no existe el directorio, también va a lanzar esta excepción, incluso si el flujo es que todavía existe.

    • +1 Esta excepción se parece ocurrir en una variedad de escenarios. Ruta no válida es uno que he encontrado hoy.
    • Hurra! Esto lo hizo para mí.
  4. 4

    Tuve el mismo problema pero en realidad la causa es que la aplicación no tiene permiso para guardar los archivos en C. Cuando he cambiado a «D:\..» la imagen se ha guardado.

  5. 2

    Copiar el mapa de bits. Usted tiene que mantener el flujo de abrir para la vida de los de mapa de bits.

    Cuando el dibujo de una imagen: Sistema.En tiempo de ejecución.InteropServices.ExternalException: Un genérico de error en 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");
        }
    • Esto no funciona exactamente; en el código en ToImage(), local de la «imagen» correctamente tienen una .RawFormat de lo que el original de archivo (jpeg o png, etc), mientras que el valor de retorno de ToImage() se inesperadamente tener .RawFormat MemoryBmp.
    • No estoy seguro de cómo la RawFormat importa mucho, sin embargo. Si usted desea usar, recuperar desde el objeto en algún lugar a lo largo del camino, pero en general, guardar como tipo que sea, en realidad se desea tenía.
  6. 2

    Este error se me ocurrió cuando yo estaba tratando de Citrix. La imagen de la carpeta C:\ en el servidor, por que no tengo privilegios. Una vez que la carpeta de la imagen fue trasladada a una unidad compartida, el error se había ido.

  7. 1

    Usted puede tratar de crear otra copia de mapa de bits:

    using (var memoryStream = new MemoryStream())
    {
        //write to memory stream here
    
        memoryStream.Position = 0;
        using (var bitmap = new Bitmap(memoryStream))
        {
            var bitmap2 = new Bitmap(bitmap);
            return bitmap2;
        }
    }
  8. 1

    Un error genérico que se produjo en GDI+. Esto puede ocurrir debido a la imagen de almacenar las rutas de problemas,tengo este error porque mi almacenar la ruta es demasiado larga, me fijo primero guardar la imagen en un camino más corto y moverlo a la ubicación correcta con una larga trayectoria manejo de las técnicas.

  9. 1

    Estaba recibiendo este error, porque el sistema automatizado de prueba que se estaba ejecutando, estaba tratando de almacenar las fotos en una carpeta que no existe. Después de haber creado la carpeta, el error se resuelve

  10. 0

    Una extraña solución que hizo que mi código para que funcione.
    Abrir la imagen en el paint y guardarla como un nuevo archivo con el mismo formato(.jpg). Ahora intenta con este nuevo archivo y funciona. Se explica claramente que el archivo podría estar dañado de alguna manera.
    Esto puede ayudar sólo si el código tiene todos los otros errores corregidos

  11. 0

    También ha aparecido conmigo cuando yo estaba tratando de guardar una imagen en la ruta de

    C:\Program Files (x86)\some_directory

    y la .exe no fue ejecutado a ejecutar como administrador, espero que esto pueda ayudar a alguien que tiene el mismo problema también.

  12. 0

    Para mí el código de abajo se estrelló con A generic error occurred in GDI+en la línea que Salva a un MemoryStream. El código se ejecuta en un servidor web y me lo resolvieron al detener e iniciar el grupo de Aplicaciones que se ejecuta el sitio.

    Debe de haber algún error interno en 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);
                    }
                }
            }
        }
  13. 0

    Me encontré con este error cuando yo estaba tratando de una simple edición de imágenes en una aplicación WPF.

    La configuración de un elemento de Imagen de la Fuente para el mapa de bits impide guardar el archivo.
    Incluso la configuración de Fuente=null no parece para liberar el archivo.

    Ahora nunca me acabo de utilizar la imagen como Fuente de elemento de Imagen, así que puede sobrescribir después de la edición!

    EDITAR

    Después de escuchar acerca de la CacheOption propiedad(Gracias a @Nyerguds) encontré la solución:
    Así que en lugar de utilizar el constructor de mapa de bits me debe establecer la Uri después de establecer CacheOption BitmapCacheOption.OnLoad.(Image1 a continuación es el de Wpf Image elemento)

    Lugar de

    Image1.Source = new BitmapImage(new Uri(filepath));

    Uso:

    var image = new BitmapImage();
    image.BeginInit();
    image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
    image.CacheOption = BitmapCacheOption.OnLoad;
    image.UriSource = new Uri(filepath);
    image.EndInit();
    Image1.Source = image;

    Ver esto: WPF almacenamiento en Caché de Imagen

    • WPF imágenes tienen un parámetro específico BitmapCacheOption.OnLoad para desconectarse de la carga de la fuente.
    • Gracias @Nyerguds, hasta que tu comentario no pude preguntar preguntas correctas
  14. 0

    Prueba este código:

    static void Main(string[] args)
    {
        byte[] data = null;
        string fullPath = @"c:\testimage.jpg";
    
        using (MemoryStream ms = new MemoryStream())
        using (Bitmap tmp = (Bitmap)Bitmap.FromFile(fullPath))
        using (Bitmap bm = new Bitmap(tmp))
        {
            bm.SetResolution(96, 96);
            using (EncoderParameters eps = new EncoderParameters(1))
            {   
                eps.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
                bm.Save(ms, GetEncoderInfo("image/jpeg"), eps);
            }
    
            data = ms.ToArray();
        }
    
        File.WriteAllBytes(fullPath, data);
    }
    
    private static ImageCodecInfo GetEncoderInfo(string mimeType)
    {
            ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();
    
            for (int j = 0; j < encoders.Length; ++j)
            {
                if (String.Equals(encoders[j].MimeType, mimeType, StringComparison.InvariantCultureIgnoreCase))
                    return encoders[j];
            }
        return null;
    }

Dejar respuesta

Please enter your comment!
Please enter your name here