2010-10-03 12 views
15

¿Por qué es que estoy recibiendo un error de falta de memoria? Graciasde Image.FromFile memoria

if (File.Exists(photoURI)) 
{ 
    FileStream fs = new FileStream(photoURI, FileMode.Open, FileAccess.Read); 
    Image img = Image.FromStream(fs); 
    fs.Close(); 
} 
+0

¿Quizás la imagen es demasiado grande? ¿Qué trataste de cargar? – schnaader

+0

una imagen, es solo 156KB – xscape

+0

¿Estás abriendo otras imágenes? ¿Qué formato de imagen? – JoshD

Respuesta

28

En la documentación Image.FromFile, un OutOfMemoryException puede haber lanzar si:

El archivo no tiene un formato de imagen válido.

-o-

GDI + no admite el formato de píxel del archivo.

Compruebe el formato de imagen.

Además, si desea cerrar la secuencia inmediatamente después de cargar la imagen, debe hacer una copia de la imagen. Eche un vistazo here. GDI + debe mantener la transmisión abierta durante toda la vida de la imagen.

+0

es un formato de archivo .png – xscape

+1

Luego, es el formato de píxel. –

+0

Intente abrir la imagen en otra aplicación y guárdela con un formato de píxel diferente. –

7

Primer error:

if (File.Exists()) 

El sistema de archivos es volátil, y por lo tanto el acceso a su archivo puede cambiar en el medio de la línea con su estado y si la línea siguiente. No solo eso, sino que File.Exists() puede devolver cierto, pero FileStream aún puede lanzar una excepción si no tiene permisos de seguridad en el archivo o si ya está bloqueado.

En cambio, la forma correcta de manejar esto es con un bloque try/catch. Dedique su tiempo de desarrollo al manejador de excepciones en su lugar, porque de todos modos tiene que escribir ese código.

segundo error:

fs.Close(); 

Esta línea debe estar dentro de un bloque finally, o tiene el potencial de dejar de archivo abierto por ahí. Normalmente recomiendo un bloque using para asegurar este tipo de recursos está dispuesto correctamente, pero puesto que ya necesita el try/catch, se puede usar un código como este en su lugar:

Image img = null; 
FileStream fs = null; 
try 
{ 
    fs = new FileStream(photoURI, FileMode.Open, FileAccess.Read);  
    img = Image.FromStream(fs);  
} 
finally 
{ 
    fs.Close(); 
} 
+2

No puede cerrar la transmisión si desea utilizar la imagen después de este punto. Eche un vistazo [aquí] (http://stackoverflow.com/questions/3661799/file-delete-failing-when-image-fromfile-was-called-prior-it-despite-making-copy/3661892#3661892). –

+0

En ese caso, me inclinaría a incluir esto en una clase con su propia implementación IDisposable que se comporta de manera más intuitiva. –

+0

fs? .Close() para C# 6 y superior. –

2

que tenían el mismo problema, a excepción de la memoria de una imagen o un mapa de bits y yo tratamos de cambiar el tamaño, la pintura en paneles y cuadros de imagen, el lote. Tenía la memoria disponible, por lo que la excepción fue un poco descabellada en mi caso.

Después de horas de patear la PC encontré que era una DLL de terceros que no estaba cerrando un arroyo. Algunos depuración 'WriteLine' que puede ser útil para comprobar si se tienen en realidad la memoria disponible:

proc = Process.GetCurrentProcess(); 
Console.WriteLine("Memory Usage" + proc.PrivateMemorySize64); 
+0

que definitivamente me dio una pista para verificar los archivos, la apertura que estaba causando el problema - usando Find Handle/DLL en Process Explorer mostró que tenían mangos abiertos mantenidos por el proceso del Sistema - tuve que cerrar los mangos manualmente (vale, no sabía lo que los mantenía, si sabía que definitivamente los cerraría normalmente) y el problema desapareció –

3

No puede utilizar Image.FromStream para su archivo, en lugar debe decodificar el archivo con TiffBitmapDecoder.El código de ejemplo de MSDN:

// Open a Stream and decode a TIFF image 
Stream imageStreamSource = new FileStream("tulipfarm.tif", FileMode.Open, FileAccess.Read, FileShare.Read); 
TiffBitmapDecoder decoder = new TiffBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); 
BitmapSource bitmapSource = decoder.Frames[0]; 

// Draw the Image 
Image myImage = new Image(); 
myImage.Source = bitmapSource; 
myImage.Stretch = Stretch.None; 
myImage.Margin = new Thickness(20); 
1

Ver this reply por Hans Passant:

GDI + fue escrito bastante tiempo antes de .NET nunca dio la vuelta. El contenedor SDK para ello se escribió en C++. Para mantenerlo compatible, no pudo usar excepciones. Las condiciones de error se informaron con códigos de error. Eso nunca escala bien, GDI + tiene solo 20 códigos de error. Eso no es mucho para un fragmento tan grande de código.

El código de error Status :: OutOfMemory se sobrecargó para significar cosas diferentes . A veces realmente significa memoria insuficiente, no puede asignar espacio suficiente para almacenar los bits del mapa de bits. Lamentablemente, no sé cómo sucedió eso , un problema de formato de archivo de imagen se informa con el mismo código de error . No hay un código de error dedicado que pueda describirlo más exactamente , supongo.

0

Desmarque Encrypt contents to secure data en las propiedades del archivo - esto me solucionó el problema.

enter image description here

Cuestiones relacionadas