2010-10-03 6 views
15

Pourquoi est-ce que je reçois une erreur de mémoire insuffisante? MerciMémoire insuffisante Image.FromFile

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

Peut-être que l'image est trop grande? Qu'avez-vous essayé de charger? – schnaader

+0

une image, son seul 156 Ko – xscape

+0

Ouvrez-vous d'autres images? Quel format d'image? – JoshD

Répondre

28

Dans la documentation Image.FromFile, un OutOfMemoryException peut être lancer si:

Le fichier n'a pas de format d'image valide.

-ou-

GDI + ne prend pas en charge le format de pixel du fichier.

Vérifiez le format de votre image.

En outre, si vous souhaitez fermer le flux juste après le chargement de l'image, vous devez faire faire une copie de l'image. Jetez un oeil here. GDI + doit garder le flux ouvert pendant toute la durée de l'image.

+0

c'est un format de fichier .png – xscape

+1

Ensuite, c'est le format de pixel. –

+0

Essayez d'ouvrir l'image dans une autre application et enregistrez-la avec un format de pixel différent. –

7

Première erreur:

if (File.Exists()) 

Le système de fichiers est volatile, et donc l'accès à votre dossier peut changer entre la ligne avec votre état et si la ligne suivante. Non seulement cela, mais File.Exists() peut renvoyer la valeur true, mais votre FileStream peut quand même générer une exception si vous ne disposez pas d'autorisations de sécurité sur le fichier ou s'il est déjà verrouillé. À la place, la façon correcte de gérer cela est avec un bloc try/catch. Consacrez plutôt votre temps de développement au gestionnaire d'exceptions, car vous devez quand même écrire ce code.

Deuxième erreur:

fs.Close(); 

Cette ligne doit être à l'intérieur d'un bloc finally, ou si vous avez la possibilité de laisser des poignées fichier ouvert traîner. Je recommande normalement un bloc using pour assurer ce type de ressource bien disposé, mais puisque vous devez déjà le try/catch, vous pouvez utiliser le code comme ceci:

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

Vous ne pouvez pas fermer le flux si vous souhaitez utiliser l'image après ce point. Jetez un coup d'oeil [ici] (http://stackoverflow.com/questions/3661799/file-delete-failing-when-image-fromfile-was-called-prior-it-despite-making-copy/3661892#3661892). –

+0

Dans ce cas, je serais enclin à envelopper dans une classe avec sa propre implémentation IDisposable qui se comporte de manière plus intuitive. –

+0

fs? .Close() pour C# 6 et plus. –

2

J'ai eu le même problème, l'exception de mémoire pour une image ou un bitmap et j'ai essayé de redimensionner, en le peignant sur des panneaux et des boîtes d'image, le lot. J'ai eu la mémoire disponible, donc l'exception était un peu un hareng rouge dans mon cas. Après des heures de démarrage du PC, j'ai découvert que c'était une DLL tierce qui ne fermait pas un flux. Certains « WriteLine » débogage qui peut être utile pour vérifier si vous n'avez réellement la mémoire disponible:

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

qui m'a certainement donné un indice pour vérifier les fichiers, ouverture qui causait le problème - en utilisant Find Handle/DLL dans Process Explorer a montré qu'ils avaient des poignées ouvertes gardées par le processus du système - je devais fermer les poignées manuellement (ok, je ne savais absolument pas ce qui les gardait - si je savais que je les fermerais normalement) et le problème a disparu –

3

Vous ne pouvez pas utiliser Image.FromStream pour votre fichier, au lieu vous devez décoder le fichier en utilisant TiffBitmapDecoder.Exemple de code 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

Voir this reply par Hans Passant:

GDI + a été écrit un certain temps avant que .NET jamais venu autour. L'emballage du SDK a été écrit en C++. Pour rester compatible, il ne peut pas utiliser d'exceptions. Les conditions d'erreur ont été signalées avec des codes d'erreur. Que n'échoue jamais bien, GDI + a seulement 20 codes d'erreur. Ce n'est pas beaucoup pour un si gros morceau de code.

Le code d'erreur Status :: OutOfMemory a été surchargé pour signifier différentes choses . Parfois, cela signifie vraiment de mémoire, il ne peut pas allouer assez d'espace pour stocker les bits bitmap. Malheureusement, je ne sais pas comment cela est arrivé, un problème de format de fichier image est signalé par le même code d'erreur . Il n'y a pas de code d'erreur dédié qui pourrait le décrire plus précisément, je suppose.

0

Décochez la case Encrypt contents to secure data dans les propriétés du fichier - cela a résolu le problème pour moi.

enter image description here

Questions connexes