2009-08-04 3 views
2

Ok, je suis désolé, c'est probablement une question noob mais je suis coincé.Créer une nouvelle image sur le système de fichiers à partir de System.Drawing.Image?

donc ce que je fais (sur mon application asp.net) est le chargement d'une image à partir du système de fichiers:

System.Drawing.Image tempImage; 
tempImage = System.Drawing.Image.FromFile(HttpContext.Server.MapPath(originalPath)); 

Puis je fais un peu Redimensionnement:

tempImage = my awesomeResizingFunction(tempImage, newSize); 

et l'intention de enregistrer dans le système de fichiers dans un autre emplacement en utilisant ceci:

string newPath = "/myAwesomePath/newImageName.jpg"; 
tempImage.Save(newPath); 

et ce que je reçois cette erreur est:Je sais que l'image est "ok" parce que je peux l'écrire au navigateur et voir l'image redimensionnée, je reçois seulement l'erreur quand j'essaye de l'enregistrer. Je suis un peu nouveau et coincé, est-ce que je fais cela totalement faux? (Eh bien, je suppose que c'est évident mais vous savez ce que je veux dire ...)

Répondre

5

plz essayer ce code ... Je l'ai utilisé le même code pour le redimensionnement image et enregistrement. Si vous avez un problème, alors faites le moi savoir.

System.Drawing.Bitmap bmpOut = new System.Drawing.Bitmap(NewWidth, NewHeight); 
    System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmpOut); 
    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 
    g.FillRectangle(System.Drawing.Brushes.White, 0, 0, NewWidth, NewHeight); 
    g.DrawImage(new System.Drawing.Bitmap(fupProduct.PostedFile.InputStream), 0, 0, NewWidth, NewHeight); 
    MemoryStream stream = new MemoryStream(); 
    switch (fupProduct.FileName.Substring(fupProduct.FileName.IndexOf('.') + 1).ToLower()) 
    { 
     case "jpg": 
      bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg); 
      break; 
     case "jpeg": 
      bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg); 
      break; 
     case "tiff": 
      bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Tiff); 
      break; 
     case "png": 
      bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Png); 
      break; 
     case "gif": 
      bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Gif); 
      break; 
    } 
    String saveImagePath = Server.MapPath("../") + "Images/Thumbnail/" + fupProduct.FileName.Substring(fupProduct.FileName.IndexOf('.')); 
    bmpOut.Save(saveImagePath); 

où fupProduct est le contrôle de fileupload ID

+1

Vous pouvez améliorer cela en utilisant Path.GetExtension au lieu de IndexOf ('.'), Bien que vous deviez modifier légèrement le commutateur http://msdn.microsoft.com/en-us/library/system.io.path .getextension.aspx – RichardOD

+0

Merci RichardOD ..... –

+0

Remarque important (http://msdn.microsoft.com/en-us/library/system.drawing.aspx)> Les classes dans l'espace de noms System.Drawing ne sont pas prises en charge pour utiliser dans un service Windows ou ASP.NET. –

0

Est-il possible que le flux d'origine sauvegardant l'image originale ait été fermé? Si le flux derrière un bitmap a été fermé, vous commencez à recevoir des erreurs GDI +. J'ai beaucoup couru quand nous avons ajouté le traitement d'image sur notre site Web.

Si vous ouvrez l'objet Bitmap dans le débogueur Visual Studio, voyez-vous des exceptions au lieu des valeurs des propriétés? Si c'est le cas, ce n'est pas un problème avec l'opération de sauvegarde, mais la couche GDI + a perdu la capacité de traiter l'objet, période. Ce que j'ai trouvé était nécessaire pour garder une trace des MemoryStreams appartenant à mes Bitmaps et les garder tous ensemble. Le redimensionnement d'une image a donné lieu à un nouveau MemoryStream avec une nouvelle image Bitmap.

Je fini par la création de cette classe simple (coupé quelques propriétés supplémentaires inutiles ici):

public class UploadedImage : IDisposable 
{ 
    private Bitmap _img = null; 
    private Stream _baseStream = null; 


    /// <summary> 
    /// The image object. This must always belong to BaseStream, or weird things can happen. 
    /// </summary> 
    public Bitmap Img 
    { 
     [DebuggerStepThrough] 
     get { return _img; } 
     [DebuggerStepThrough] 
     set { _img = value; } 
    } 

    /// <summary> 
    /// The stream that stores the image. This must ALWAYS belong to Img, or weird things can happen. 
    /// </summary> 
    public Stream BaseStream 
    { 
     [DebuggerStepThrough] 
     get { return _baseStream; } 
     [DebuggerStepThrough] 
     set { _baseStream = value; } 
    } 

    [DebuggerStepThrough] 
    public void Dispose() 
    { 
     if (Img != null) 
      Img.Dispose(); 

     if (BaseStream != null) 
      BaseStream.Close(); 

     _attached = false; 
    } 
} 

Maintenant, je traitais des images téléchargées sur notre site Web, et ce que j'ai trouvé que lorsque Asp.Net recyclé le flux attaché à la demande, toutes les opérations d'image soudaines ont commencé à flipper. Donc, ma solution, que ce soit la meilleure façon de le faire ou non, était de copier les données du flux de téléchargement vers mon propre MemoryStream, charger l'image à partir de cela, et coller les deux dans ce conteneur. Et partout où j'ai créé une nouvelle image à partir d'un ancien, j'ai toujours gardé le flux et l'image ensemble.

J'espère que cela aide.

EDIT: Je suis également intéressé de voir comment vous faites le redimensionnement de l'image. Ceci est un extrait de la façon dont je l'ai fait la nôtre:

temp = new Bitmap(newWidth, newHeight, PIXEL_FORMAT); 
temp.SetResolution(newHorizontalRes, newVerticalRes); 
gr = Graphics.FromImage(temp); 

// 
// This copies the active frame from 'img' to the new 'temp' bitmap. 
// Also resizes it and makes it super shiny. Sparkle on, mr image dude. 
// 
Rectangle rect = new Rectangle(0, 0, newWidth, newHeight); 
gr.InterpolationMode = InterpolationMode.HighQualityBicubic; 
gr.SmoothingMode = SmoothingMode.HighSpeed; 
gr.PageUnit = GraphicsUnit.Pixel; 
gr.DrawImage(img, rect); 

// 
// Image copied onto the new bitmap. Save the bitmap to a fresh memory stream. 
// 
retval = new UploadedImage(); 
retval.BaseStream = (Stream)(new MemoryStream()); 

temp.Save(retval.BaseStream, ImageFormat.Jpeg); 
retval.Img = temp; 
+0

Remarque importante (http://msdn.microsoft.com/en-us/library/system.drawing.aspx)> Les classes au sein de l'espace de noms System.Drawing sont non pris en charge pour une utilisation dans un service Windows ou ASP.NET. –

2

Êtes-vous sûr que le originalPath et le point Newpath aux fichiers différents? Lorsque vous utilisez Image.FromFile, le fichier reste verrouillé jusqu'à ce que vous appelez Dispose sur l'image, ce qui peut conduire à l'exception que vous avez mentionnée. Vous pouvez charger l'image comme ça à la place:

Image tempImage = null; 
using (FileStream fs = new FileStream(originalPath, FileMode.Open, FileAccess.Read)) 
{ 
    tempImage = Image.FromStream(fs); 
} 
... 

Cette approche garantit que le fichier est fermé à la fin du bloc à l'aide

Questions connexes