2011-03-21 4 views
0

J'essaie de créer des vignettes. mon chemin vers le dossier original est: supposons I: \ mes images **, et je veux le générer à ** i: \ nouvelles images. J'ai eu deux problème, premier problème est que si mon dossier images contient sous-dossier puis dans les nouvelles images, il devrait également être dans le sous-dossier pas comme un dossier parent.erreur de génération de vignettes C#

  • seconde i a une erreur. ** Une erreur générique est produite dans GDI +.

    3 i obtenir cette erreur. Mémoire insuffisante **

son une application console csharp

at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams) 
at System.Drawing.Image.Save(String filename, ImageFormat format) 
at ConsoleApplication1.Program.CreateThumbnail(String[] b, Double wid, Double hght, Boolean Isprint) 

public void CreateThumbnail(string[] b, double wid, double hght, bool Isprint) 
{ 
    string[] path; 
    path = new string [64]; 
    path = b; 
    string saveath = "i:\\check\\a test\\"; 
    for (int i = 0; i < b.Length; i++) 
    { 
     DirectoryInfo dir = new DirectoryInfo(path[i]); 
     string dir1 = dir.ToString(); 
     dir1 = dir1.Substring(dir1.LastIndexOf("\\")); 

     FileInfo[] files1 = dir.GetFiles(); 

     foreach (FileInfo f in files1) 
     { 
      string gh = f.ToString(); 
      try 
      { 
       System.Drawing.Image myThumbnail150; 
       System.Drawing.Image.GetThumbnailImageAbort myCallback = new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback); 
       System.Drawing.Image imagesize = System.Drawing.Image.FromFile(f.FullName); 
       Bitmap bitmapNew = new Bitmap(imagesize); 
       double maxWidth = wid; 
       double maxHeight = hght; 
       int w = imagesize.Width; 
       int h = imagesize.Height; 
       // Longest and shortest dimension 
       int longestDimension = (w > h) ? w : h; 
       int shortestDimension = (w < h) ? w : h; 
       // propotionality 
       float factor = ((float)longestDimension)/shortestDimension; 
       // default width is greater than height  
       double newWidth = maxWidth; 
       double newHeight = maxWidth/factor; 
       // if height greater than width recalculate 
       if (w < h) 
       { 
        newWidth = maxHeight/factor; 
        newHeight = maxHeight; 
       } 
       myThumbnail150 = bitmapNew.GetThumbnailImage((int)newWidth, (int)newHeight, myCallback, IntPtr.Zero); 

       string ext = Path.GetExtension(f.Name); 

       if (!Directory.Exists(saveath + dir1)) 
       { 
        Directory.CreateDirectory(saveath + dir1); 
        myThumbnail150.Save(saveath + dir1 + "\\" + f.Name.Replace(ext, ".Jpeg"), System.Drawing.Imaging.ImageFormat.Jpeg); 
       } 
       else if(Directory.Exists(saveath+dir1)) 
       { 
        myThumbnail150.Save(saveath + dir1+" \\"+ f.Name.Replace(ext, ".Jpeg"), System.Drawing.Imaging.ImageFormat.Jpeg); 
       } 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("something went wrong" + ex.ToString()); 
      } 
     } 
    } 
} 
+0

Où exactement obtenez-vous les exceptions 2 et 3? Je me souviens de ces exceptions lorsque je travaillais avec SQL Server Reporting Services générant des rapports pleins d'images. Les exceptions tirées après le processus ont essayé de consommer plus de 2 Go de mémoire sur une installation Windows 32 bits. Souvenez-vous que les processus sont limités à la quantité de mémoire qu'ils peuvent traiter (peu importe la quantité de mémoire que vous avez réellement dans votre ordinateur). En outre, vous voudrez peut-être envisager de disposer de vos objets GDI. J'ai déjà travaillé avec du GDI + non géré et vous devez nettoyer après avoir utilisé les objets. – enriquein

+0

@Ernriquein Je reçois ces erreurs après le traitement de certains fichiers, disons que le dossier contient 30 images, après avoir traité 17 images, il donne cette erreur. J'ai 64 bits Windows 7 installés. – safi

Répondre

3

Je viens refondus un peu le code et maintenant il fonctionne (sur ma machine):

private static void CreateThumbnail(string[] b, double wid, double hght, bool Isprint) 
{ 
    string saveAt = "D:\\check"; 
    foreach (string path in b) 
    { 
     var directory = new DirectoryInfo(path); 
     string outputPath = Path.Combine(saveAt, directory.Name); 
     foreach (FileInfo f in directory.GetFiles("*.*", SearchOption.AllDirectories)) 
     { 
      if (f.DirectoryName != directory.FullName) 
      { 
       outputPath = Path.Combine(saveAt, directory.Name, f.Directory.Name); 
      } 
      if (!Directory.Exists(outputPath)) 
      { 
       Directory.CreateDirectory(outputPath); 
      } 

      using (Image imagesize = Image.FromFile(f.FullName)) 
      using (Bitmap bitmapNew = new Bitmap(imagesize)) 
      { 
       double maxWidth = wid; 
       double maxHeight = hght; 
       int w = imagesize.Width; 
       int h = imagesize.Height; 
       // Longest and shortest dimension 
       int longestDimension = (w > h) ? w : h; 
       int shortestDimension = (w < h) ? w : h; 
       // propotionality 
       float factor = ((float)longestDimension)/shortestDimension; 
       // default width is greater than height  
       double newWidth = maxWidth; 
       double newHeight = maxWidth/factor; 
       // if height greater than width recalculate 
       if (w < h) 
       { 
        newWidth = maxHeight/factor; 
        newHeight = maxHeight; 
       } 

       string fileName = Path.Combine(outputPath, Path.GetFileNameWithoutExtension(f.Name) + ".jpeg"); 
       bitmapNew.GetThumbnailImage((int)newWidth, (int)newHeight,() => false, IntPtr.Zero) 
        .Save(fileName, System.Drawing.Imaging.ImageFormat.Jpeg); 
      } 
     } 
    } 
} 

Je dois dire que peu mince gs à propos de votre ancien code:

  • utilisez foreach si possible;
  • éviter les trois premières lignes, ils sont inutiles;
  • éviter les variables inutilisées;
  • gardez votre code aussi propre que possible;
+0

@ As-CII merci beaucoup je vais essayer maintenant, résout-il le problème de sous-dossier aussi? – safi

+0

Oui, maintenant il ne :) –

+0

@ AS-Cil 'Bitmap bitmapNew = new Bitmap (imagesize);' Mémoire insuffisante sur cette ligne. – safi

1

A propos de la "GDI + erreur générique" et "Out Of Memory" exceptions, vous devriez jeter un oeil à ce lien sur SO: What is the "best" way to create a thumbnail using ASP.NET?

Vous devez utiliser l'instruction C# using pour vous assurer que GDI non géré + les ressources sous la surface .NET sont libérées le plus rapidement possible pour éviter les erreurs de mémoire insuffisante.

Le GDI + générique peut se produire si l'image ne peut pas être converti par exemple.

+0

Merci, je vais regarder :) – safi

Questions connexes