2010-03-21 3 views
2

Ce code fonctionne très bien pour générer des vignettes, mais lorsqu'il reçoit un très gros fichier TIFF (100MB +), il renvoie OutOfMemoryExceptions. Lorsque je le fais manuellement dans Paint.NET sur la même machine, cela fonctionne très bien. Comment puis-je améliorer ce code pour arrêter de lancer sur de très gros fichiers?Pourquoi ce code de génération de vignettes renvoie OutOfMemoryException sur les fichiers volumineux?

Dans ce cas, je charge un TIF de 721 Mo sur une machine avec 8 Go de RAM. Le gestionnaire de tâches montre 2 Go utilisé donc quelque chose l'empêche de en utilisant toute cette mémoire. Spécifiquement, il se lance lorsque je charge l'image pour calculer la taille de l'original. Ce qui donne?

/// <summary>Creates a thumbnail of a given image.</summary> 
/// <param name="inFile">Fully qualified path to file to create a thumbnail of</param> 
/// <param name="outFile">Fully qualified path to created thumbnail</param> 
/// <param name="x">Width of thumbnail</param> 
/// <returns>flag; result = is success</returns> 
public static bool CreateThumbnail(string inFile, string outFile, int x) 
{ 
    // Mathematically determine Y dimension 
    int y; 
    using (Image img = Image.FromFile(inFile)) // Exception thrown 
     y = (int)((double)img.Height * ((double)x/(double)img.Width)); 

    // Make thumbnail  
    using (Bitmap bmp = new Bitmap(inFile)) 
    using (Bitmap thumb = new Bitmap((Image)bmp, new Size(x, y))) 
     using (Graphics g = Graphics.FromImage(thumb)) { 
     g.SmoothingMode = SmoothingMode.HighQuality; 
     g.InterpolationMode = InterpolationMode.High; 
     g.CompositingQuality = CompositingQuality.HighQuality; 
     ImageCodecInfo codec = ImageCodecInfo.GetImageEncoders()[1]; 
     EncoderParameters ep2 = new EncoderParameters(1); 
     ep2.Param[0] = new EncoderParameter(Encoder.Quality, 100L); 
     g.DrawImage(bmp, new Rectangle(0,0,thumb.Width, thumb.Height)); 
     try { 
      thumb.Save(outFile, codec, ep2); 
      return true; } 
     catch { return false; } 
     } 
} 
+1

Est-ce que cela se produit avec toutes les images de cette taille ou avec des instances particulières? Je sais que je reçois OOM de GDI pour certaines images indépendamment de leur taille et cela finit généralement par ne pas sauter par les bons cerceaux GDI pour le flux en cours. –

+0

Chaque très grande image, JPG ou TIF. Principalement TIF juste parce que c'est la plupart de mon "imagebase". Fonctionne très bien pour les fichiers de moins de 100 Mo, et certains de mes TIF vont dans les Go. – tsilb

+0

tsilb: J'ai saisi le code de validation (car il n'a pas touché le fichier) et pressé le formatage pour rendre le bloc de code moins intimidant. Veuillez revenir en arrière si vous pensez que ces changements ont éliminé quelque chose d'important. – itowlson

Répondre

1

Ma conjecture sauvage est que, vous l'exécutez comme une application 32 bits. Ce qui limite l'utilisation de la mémoire de votre application à 2 Go théoriques, ce qui correspond plus à 1,5 Go empiriquement.

+0

Se produit à la fois dans Prod dans un pool d'applications .NET 4.0, IIS 6, x64 OS; et en débogage sur une machine x64 avec vs2010 rc x64 ... pas sûr de savoir comment vérifier que ... – tsilb

+0

Si vous exécutez vraiment le processus dans un environnement Windows x64, vous pouvez vérifier si l'application s'exécute en tant que x86 en l'ouvrant votre gestionnaire de tâches et localiser le processus de votre application. S'il n'a pas de * 32, ma conjecture sauvage est fausse. – Anzurio

+0

Dang, tu as raison. On dirait que 64 bits peut être fait en VS mais cela rend le débogage presque impossible. Que diriez-vous d'un moyen de le faire fonctionner à partir de IIS? – tsilb

0

Avez-vous essayé avec FastImageGDIPlus. Cela a bien fonctionné pour moi - mais je n'ai jamais essayé de charger un fichier de 721 Mo.

Questions connexes