Domanda

Ok, mi dispiace, questa è probabilmente una domanda noob ma sono un po 'bloccato.

Quindi quello che sto facendo (sulla mia applicazione asp.net) è caricare un'immagine dal file system:

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

Quindi eseguo alcuni ridimensionamenti:

tempImage = my awesomeResizingFunction(tempImage, newSize);

e intendo salvarlo nel file system in un'altra posizione usando questo:

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

e quello che ottengo è questo errore:

"A generic error occurred in GDI+."

So che l'immagine è " ok " poiché posso scriverlo sul browser e vedere l'immagine ridimensionata, ottengo l'errore solo quando provo a salvarlo. Sono un po 'nuovo e bloccato, sto sbagliando tutto? (Beh, suppongo sia ovvio ma sai cosa intendo ...)

È stato utile?

Soluzione

per favore prova questo codice ... Ho usato lo stesso codice per ridimensionare l'immagine e salvarla. se riscontri problemi, per favore fammi sapere.

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);

dove fupProduct è l'ID controllo fileupload

Altri suggerimenti

Sei sicuro che originalPath e newPath puntino a file diversi? Quando si utilizza Image.FromFile, il file rimane bloccato fino a quando non si chiama Dispose sull'immagine, il che può portare all'eccezione menzionata. Puoi invece caricare l'immagine in questo modo:

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

Questo approccio garantisce che il file sia chiuso alla fine del blocco using

È possibile che lo stream originale che supporta l'immagine originale sia stato chiuso? Se lo stream dietro una Bitmap è stato chiuso, inizi a ricevere errori GDI +. Mi sono imbattuto molto in questo quando abbiamo aggiunto l'elaborazione delle immagini al nostro sito web.

Se si apre l'oggetto Bitmap nel debugger di Visual Studio, vengono visualizzate eccezioni anziché i valori delle proprietà? In tal caso, non è un problema con l'operazione di salvataggio, ma il livello GDI + ha perso la capacità di elaborare l'oggetto, punto.

Quello che ho scoperto era che dovevo tenere traccia dei flussi di memoria appartenenti alle mie bitmap e tenerli tutti insieme. Il ridimensionamento di un'immagine ha comportato un nuovo MemoryStream con una nuova immagine Bitmap.

Ho finito per creare questa semplice classe (ho eliminato alcune proprietà extra non necessarie qui):

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;
    }
}

Ora, avevo a che fare con le immagini caricate sul nostro sito Web, e quello che ho scoperto è stato che quando Asp.Net ha riciclato il flusso allegato alla Richiesta, tutte le improvvise operazioni di immagine hanno iniziato a fallire. Quindi, la mia soluzione, che fosse il modo migliore per farlo o no, era copiare i dati dal flusso di upload sul mio MemoryStream, caricare l'immagine da quello e incollarli entrambi in questo contenitore. E ovunque ho creato una nuova immagine da una vecchia, ho sempre tenuto insieme il flusso e l'immagine.

Spero che questo aiuti.

EDIT: sono anche interessato a vedere come stai facendo il ridimensionamento dell'immagine. Questo è uno snippet di come ho fatto il nostro:

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;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top