locked
GDI+ Generic Error for some images but not others - Any Advice? C# RRS feed

  • Question

  • User827376954 posted

    I've been reading through page after page of resources trying to figure out what is causing this problem. I am hoping someone here might have some advice. The code below works for most of the images provided to it - all of which are .tif. However, we have an occassional .tif file that does not like this code and returns an error as follows:

    System.Runtime.InteropServices.ExternalException (0x80004005): A generic error occurred in GDI+.
       at System.Drawing.Image.Save(Stream stream, ImageCodecInfo encoder, EncoderParameters encoderParams)
       at System.Drawing.Image.Save(Stream stream, ImageFormat format)
    

    I know it's not a permissions issue, as we're just writing out to the memory stream, and I've verified that we have no difficulty loading the image into the initial file stream. It's not an issue with closing a stream too early. It's not because I'm resaving over a file that is still in use. The real head-scratcher for me is that I've opened a working and a faulty .tif file in image program and compared the two images - and as far as properties, they seem almost identical, albeit the images are different dimensions. According to IrfanView, they are the same dpi with the same compression (CCITT Group 4 Fax Encoding). I've even tried adding the try-catch at the bottom to try it as a bitmap instead - exact same result.

    I'm at my wits end here. Any advice would greatly be appreciated.

    Code not shown: fs1 is loaded with a .tif file.

    protected virtual void ShowMeImage(Stream fs1)
            {
                string _type = Request.QueryString["type"];
    
                if (_type == "" || _type == null) _type = "PNG";
    
                System.Drawing.Image img = System.Drawing.Image.FromStream(fs1);
                System.Drawing.Imaging.ImageFormat imf = System.Drawing.Imaging.ImageFormat.Png;
    
                switch (_type.ToLower())
                {
                    case "jpg":
                        imf = System.Drawing.Imaging.ImageFormat.Jpeg;
                        break;
                    case "gif":
                        imf = System.Drawing.Imaging.ImageFormat.Gif;
                        break;
                    case "png":
                    default:
                        break;
                }
    
                string sTempPath = Path.GetTempPath();
    
                _finalOutput = new MemoryStream();
    
                try
                {
                    img.Save(_finalOutput, imf);
                }
                catch
                {
                    img = System.Drawing.Bitmap.FromStream(fs1);
                    img.Save(_finalOutput, imf);
                }
    
                if (fs1 != null)
                {
                    fs1.Dispose();
                }
    
    
            }



    Tuesday, January 22, 2013 10:09 AM

Answers

All replies

  • User-2131313413 posted

    In your code you create sTempPath however you do not use it.

    Where does img.Save actually save?

    I understand you use the MemoryStream but the memory stream does not point a specific folder/file location

    Could it be that the application memory limit is reached

    Does the error occur every 6 images or every 5mb or something of a like?

     

    Friday, January 25, 2013 7:36 AM
  • User827376954 posted

    In your code you create sTempPath however you do not use it.

    Oh, you're right. That is a left over line from an image rotating code that was stripped out of the code.

    Where does img.Save actually save?

    I understand you use the MemoryStream but the memory stream does not point a specific folder/file location

    I'm still a bit new to this, so my apologies if I'm not understanding this correctly, but once it is saved to the memory stream, it appears to be displayed in the web browser accessing the page referencing this class. Basically, the process pulls in images from the file system and displays them in the browser. It has to pass through this class so that various functions can be done to the image if needed (rotating, resizing, etc.).

    Could it be that the application memory limit is reached

    Does the error occur every 6 images or every 5mb or something of a like?

    It isn't very likely. Basically, it only happens with specific images provided to us by a vendor. Because they're .tiff images, based on research I've done, I'm starting to think that this could be due to the server's OS being too old to handle the processing of something in the .tiff image itself. Unfortunately, I haven't been able to get a copy of a server yet to test it out, but I know I'm not getting the error in my own local debugs. The error is only produced on a Windows 2008 Web Edition server.

    Does this sound like it could be the likely culprit? Unfortunately, most of the time these Generic GDI+ errors appear to be permission-based or related to closing a stream too early or trying to save over an image you're still using. As such, I've had to look through something like 80 forum posts so far describing various GDI+ errors just to arrive at this possible conclusion.

    Friday, January 25, 2013 5:20 PM
  • User-2131313413 posted

    The server version could be the culprit, however I cannot say for 100%

    I sometimes get an GDI+ error when working with images and closing streams to early so I know what you are talking about, however from the error message because it hits it at the Save.

    Just looking at your code again, whave you tried changing the try/catch block to

    try
    {
    img.save(your parameters);
    }
    catch (ex Exception)
    {
    //perhaps for debuging create a lbl on page and fill it with error
    lblError.Text = ex.InnerMessage;
    }
    
    

    Only reason im suggesting this is because in your try/catch block if it tries but fails, instead of catching an error it fails AGAIN as you trying to save it again.

    After the try/catch dont check if fs1 is null, just dispose of it

    If that doesn't work, consider the possibility that your "img" variable is in use from the line where you tell it to draw an image from a stream.

    Create a BITMAP variable and copy the "img" image into the variable and dispose of img so you can safely call Save on the new Bitmap variable


     

    Wednesday, January 30, 2013 9:17 AM
  • User-2131313413 posted

    just to backup my previous reply..

    on this forum there was the solution for copying the image to another instance of the image which a lot of people found works

    http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/b15357f1-ad9d-4c80-9ec1-92c786cca4e6/

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, January 31, 2013 10:25 AM