Question

Ok, je suis désolé, c'est probablement une question de noob mais je suis un peu coincé.

Donc, ce que je fais (sur mon application asp.net), c'est de charger une image à partir du système de fichiers:

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

Ensuite, je redimensionne:

tempImage = my awesomeResizingFunction(tempImage, newSize);

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

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

et ce que je reçois est cette erreur:

"A generic error occurred in GDI+."

Je sais que l'image est "ok". parce que je peux l'écrire dans le navigateur et voir l'image redimensionnée, je n'obtiens l'erreur que lorsque j'essaie de la sauvegarder. Je suis un peu nouveau et coincé, est-ce que je fais totalement faux? (Eh bien, je suppose que c'est évident, mais vous voyez ce que je veux dire ...)

Était-ce utile?

La solution

plz essayez ce code ... J'ai utilisé le même code pour redimensionner et enregistrer une image. si vous rencontrez un problème, merci de me le faire 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 l'ID de contrôle fileupload

Autres conseils

Êtes-vous sûr que le chemin originalPath et le chemin newPath pointent vers des fichiers différents? Lorsque vous utilisez Image.FromFile, le fichier reste verrouillé jusqu'à ce que vous appeliez Dispose sur l'image, ce qui peut entraîner 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 using

Est-il possible que le flux d'origine sauvegardant l'image d'origine ait été fermé? Si le flux derrière un bitmap a été fermé, vous commencez à obtenir des erreurs GDI +. Je me suis souvent heurté à cela lorsque nous avons ajouté le traitement d'images à notre site Web.

Si vous ouvrez l'objet Bitmap dans le débogueur Visual Studio, voyez-vous des exceptions à la place des valeurs des propriétés? Si tel est le cas, la sauvegarde ne pose pas de problème, mais la couche GDI + a perdu la capacité de traiter l’objet, point final.

Ce que j’ai découvert, c’est que j’avais besoin de garder une trace des MemoryStreams appartenant à mes bitmaps et de les conserver tous ensemble. Le redimensionnement d'une image a donné lieu à un nouveau MemoryStream avec une nouvelle image Bitmap.

J'ai fini par créer cette classe simple (avec 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 avec des images téléchargées sur notre site Web. Ce que j’ai découvert, c’est que, lorsque Asp.Net a recyclé le flux attaché à la demande, toutes les opérations soudaines sur les images ont commencé à s’écrouler. 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, de charger l'image à partir de celle-ci et de les coller dans ce conteneur. Et chaque fois que j'ai créé une nouvelle image à partir d'une ancienne, j'ai toujours gardé le flux et l'image ensemble.

J'espère que cela vous aidera.

EDIT: Je voudrais aussi voir comment vous redimensionnez l’image. Voici un extrait de ce que j'ai fait pour nous:

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;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top