添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
飞翔的皮带  ·  PostgreSQL ...·  8 月前    · 
温暖的八宝粥  ·  Disable cursor ...·  10 月前    · 
想出家的绿茶  ·  aws的elastic ip ...·  1 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Ok, I'm sorry, this is probably a noob question but I'm kinda stuck.

So what I'm doing (on my asp.net application) is loading an image from the file system:

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

Then I do some resizing:

tempImage = my awesomeResizingFunction(tempImage, newSize);

and intend to save it to the file system in another location using this:

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

and what I get is this error:

"A generic error occurred in GDI+."

I know the image is "ok" because I can write it out to the browser and see the resized image, I only get the error when I try to save it. I'm kinda new and stuck, am I doing this totally wrong? (Well, i guess that's obvious but you know what I mean...)

Try this code... I have used the same code for resizing image and saving.

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

where fupProduct is fileupload control ID

You could improve this by using Path.GetExtension instead of IndexOf('.'), though you'd have to modify the switch slightly msdn.microsoft.com/en-us/library/… – RichardOD Sep 29, 2009 at 10:45 Note importantly (msdn.microsoft.com/en-us/library/system.drawing.aspx) > Classes within the System.Drawing namespace are not supported for use within a Windows or ASP.NET service. – Marc Gravell Oct 16, 2009 at 11:25

Are you sure that the originalPath and newPath point to different files ? When you use Image.FromFile, the file remains locked until you call Dispose on the Image, which can lead to the exception you mentioned. You could load the image like that instead :

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

This approach guarantees that the file is closed at the end of the using block

Is it possible the original stream backing the original image has been closed? If the stream behind a Bitmap has been closed, you start getting GDI+ errors. I ran into this a lot when we added image processing to our website.

If you open up the Bitmap object in the Visual Studio debugger, do you see exceptions instead of the values of the properties? If so, it's not a problem with the save operation, but the GDI+ layer has lost the ability to process the object, period.

What I found was I needed to keep track of the MemoryStreams belonging to my Bitmaps and keep them all together. Resizing an image resulted in a new MemoryStream with a new Bitmap image.

I ended up creating this simple class (trimmed some extra properties unneeded here):

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;

Now, I was dealing with images uploaded to our website, and what I found was that when Asp.Net recycled the stream attached to the Request, all the sudden image operations started flipping out. So, my solution, whether this was the best way to do it or not, was to copy the data from the upload stream to my own MemoryStream, load the image from that, and stick both into this container. And wherever I created a new image from an old one, I always kept the stream and the image together.

I hope this helps.

EDIT: I'm also interested in seeing how you're doing the image resizing. This is a snippet of how I did ours:

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;
                Note importantly (msdn.microsoft.com/en-us/library/system.drawing.aspx) > Classes within the System.Drawing namespace are not supported for use within a Windows or ASP.NET service.
– Marc Gravell
                Oct 16, 2009 at 11:28
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.