asp.net - net - Excepción de memoria insuficiente en System.Drawing.Image.FromFile()
system drawing dll (10)
Estoy teniendo el mismo problema de procesamiento por lotes de archivos Tiff. La mayoría de los archivos no arrojan una excepción, pero pocos archivos arrojan una excepción de "Memoria insuficiente" en ASP.NET 4.0. He usado datos binarios para descubrir por qué solo para algunos archivos y desde la misma carpeta. No puede tratarse de un problema de permiso para ASP.NET ASPNET o NETWORK SERVICE account porque otros archivos son archivos de trabajo.
Abrí la clase iTextSharp.text.Image y descubrí que hay muchos métodos sobrecargados para GetInstance (). He resuelto mi problema usando el siguiente código: nota: catch block se ejecutará para archivos problemáticos.
iTextSharp.text.Image image = null;
try
{
var imgStream = GetImageStream(path);
image = iTextSharp.text.Image.GetInstance(imgStream);
}
catch {
iTextSharp.text.pdf.RandomAccessFileOrArray ra = null;
ra = new iTextSharp.text.pdf.RandomAccessFileOrArray(path);
image = iTextSharp.text.pdf.codec.TiffImage.GetTiffImage(ra, 1);
if (ra != null)
ra.Close();
}
Tengo un cargador de imágenes y un cortador que crea miniaturas y de vez en cuando obtengo una excepción de falta de memoria en la siguiente línea:
Dim bm As Bitmap = System.Drawing.Image.FromFile(imageFile)
La ocurrencia del error es pequeña y muy rara, pero siempre me gusta saber qué podría estar causando esto. La variable imageFile es solo un Server.MapPath para la ruta de la imagen.
Tenía curiosidad si alguien había experimentado este problema anteriormente y si tenían alguna idea de lo que podría estar causando? ¿Es el tamaño de la imagen quizás?
Puedo publicar el código si es necesario y cualquier información de respaldo que tenga, pero me encantaría escuchar las opiniones de la gente sobre este.
He tenido el mismo problema, antes de buscar en otro lugar en el código quería asegurarse de que si puedo abrir la imagen con cualquier visor de imágenes y descubrí que la imagen está dañada / dañada a pesar de que es un archivo .PNG con 1 KB de tamaño. Se agregó una nueva imagen en la misma ubicación, luego funcionó bien.
Llegué al mismo problema hoy al crear imágenes en miniatura para una carpeta llena de imágenes. Resulta que el "Sin memoria" ocurrió exactamente en el mismo punto cada vez. Cuando miré la carpeta con las imágenes a convertir, encontré que el archivo que creaba el problema era thumbs.db. Agregué un código para asegurarme de que solo se convertían los archivos de imagen y se resolvió el problema.
Mi código es básicamente
For Each imageFile as FileInfo in fileList
If imageFile.Extension = ".jpg" Or imageFile.Extension = ".gif" Then
...proceed with the conversion
End If
Next
Espero que esto ayude.
Si este no era un archivo de imagen incorrecto, sino que de hecho era el problema normal con Image.FromFile
en el que deja abiertos los identificadores de archivo, la solución es utilizar Image.FromStream
lugar.
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
using (Image original = Image.FromStream(fs))
{
...
Usar una declaración explícita de Dispose()
, una instrucción using()
o establecer el valor en null
en el mapa de bits no resuelve el problema con Image.FromFile
.
Entonces, si su aplicación se ejecuta durante un tiempo y abre una gran cantidad de archivos, considere usar Image.FromStream()
lugar.
Si una imagen es un icono, se requiere un manejo de carga diferente, como en la siguiente función:
public static Image loadImage(string imagePath)
{
Image loadedImage = null;
if (!File.Exists(imagePath)) return loadedImage;
try
{
FileInfo fileInfo = new FileInfo(imagePath);
if (fileInfo.Extension.Equals(".jpg") || fileInfo.Extension.Equals(".jpeg") ||
fileInfo.Extension.Equals(".bmp") || fileInfo.Extension.Equals(".png") ||
fileInfo.Extension.Equals(".gif"))
{
loadedImage = Image.FromFile(imagePath);
}
else if (fileInfo.Extension.Equals(".ico"))
{
Bitmap aBitmap = Bitmap.FromHicon(new
Icon(imagePath, new Size(200, 200)).Handle);
loadedImage = ImageFuncs.ResizeImage(aBitmap, new Size(30, 30));
}
}
catch (Exception eLocal)
{
MessageBox.Show(imagePath + " loading error: " + eLocal.Message);
}
return loadedImage;
}
También puede abrirlo en modo lectura, (si desea usarlo en dos lugares al mismo tiempo)
public Image OpenImage(string previewFile)
{
FileStream fs = new FileStream(previewFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return Image.FromStream(fs);
}
También verifique si no ha abierto el mismo archivo en otro lugar. Aparentemente, cuando abre un archivo dos veces (incluso con File.Open ()) OutOfMemoryException se lanza también ...
Tuve el mismo problema con una utilidad que escribí para convertir TIFF (s) a PDF (s). A menudo me sale el error de "falta de memoria" en la misma línea que tú.
System.Drawing.Image.FromFile(imageFile)
Entonces descubrí que el error solo ocurría cuando la extensión del archivo era ".tiff" y funcionaba bien después de que le cambiara el nombre por una extensión de ".tif"
Tuve un problema similar hoy cuando estaba tratando de cambiar el tamaño de una imagen y luego recortarla, lo que sucedió es que utilicé este código para cambiar el tamaño de la imagen.
private static Image resizeImage(Image imgToResize, Size size)
{
int sourceWidth = imgToResize.Width;
int sourceHeight = imgToResize.Height;
float nPercent = 0;
float nPercentW = 0;
float nPercentH = 0;
nPercentW = ((float)size.Width / (float)sourceWidth);
nPercentH = ((float)size.Height / (float)sourceHeight);
if (nPercentH < nPercentW)
nPercent = nPercentH;
else
nPercent = nPercentW;
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
Bitmap b = new Bitmap(destWidth, destHeight);
Graphics g = Graphics.FromImage((Image)b);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
g.Dispose();
return (Image)b;
}
Y luego este código para el cultivo ...
private static Image cropImage(Image img, Rectangle cropArea)
{
Bitmap bmpImage = new Bitmap(img);
Bitmap bmpCrop = bmpImage.Clone(cropArea,
bmpImage.PixelFormat);
return (Image)(bmpCrop);
}
Entonces así es como llamé al código anterior ...
Image img = Image.FromFile(@"C:/Users/****/Pictures/image.jpg");
img = ImageHandler.ResizeImage(img, new Size(400, 300));
img = ImageHandler.CropImage(img, new Rectangle(0, 25, 400, 250));
long quality = 90;
Seguí recibiendo errores en la parte de recorte, ¡el redimensionador funcionó bien!
Resulta que lo que sucedía dentro del resizer estaba arrojando errores en la función de recorte. Los cálculos redimensionados hacían que las dimensiones reales de la imagen fueran como 399 en lugar de 400 en las que pasé.
Entonces, cuando pasé en 400 como el argumento para el cultivo, estaba tratando de recortar una imagen de 399px de ancho con un ancho de 400px bmp y arrojó el error de memoria insuficiente.
La mayoría del código anterior se encontró en http://www.switchonthecode.com/tutorials/csharp-tutorial-image-editing-saving-cropping-and-resizing
Vale la pena saber que OutOfMemoryException no siempre significa que se ha quedado sin memoria, especialmente cuando se trata de archivos. Creo que también puede suceder si se queda sin asas por alguna razón.
¿Estás desechando todos tus mapas de bits una vez que termines con ellos? ¿Esto sucede repetitivamente para una sola imagen?