A Generic error occurs at GDI+ at Bitmap.Save() after using SaveFileDialog
Asked Answered
C

11

27

I use the following code block with some more code inside the using block:

using (System.Drawing.Bitmap tempImg =
       (System.Drawing.Bitmap)tempObj.GetData(System.Windows.Forms.DataFormats.Bitmap))
{
    // ...
    tempImg.Save("..\\..\\testdata\\tempImg.bmp", ImageFormat.Bmp);                            
    // ...
}

But I still get the error:

A Generic Error occured at GDI+

only after I make some action which is not related to the code inside the using block. In other times this works well. Also the tempImg.bmp is a temporary file, so I delete the tempImg.bmp within the using block itself.

Since the tempImg is inside the using and this it's disposed, I think the locking problem should be solved.

Can someone please let me know what is the mistake in this code?

Edit: System.Drawing.Image to System.Drawing.Bitmap as the type of tempImg.

Edit: I have identified I get this error only after SaveFileDialog is created and user clicks on 'Save'.

Cardinal answered 28/4, 2011 at 4:28 Comment(5)
Why is tempImg Image and your cast Bitmap ?Albigenses
Sorry, it should be corrected as SYstem.Drawing.Bitmap... thanks for commentCardinal
only after I make some action which is not related to the code does this involve reading/saving some other image ?Albigenses
No, it only create an avi file using the Bitmap objects obtained from tempImg though a stream within the using block itselft and tempImg.bmp is deleted each time after obtaining the bitmap object.Cardinal
So that might be the problem since its already in use by the process, post that code so it would be more relevantAlbigenses
C
43

Finally I could find what was wrong in my code and would like to mention it here as I think it may be useful to someone....

As I have given a relative path in tempImg.Save, and after the user clicks 'Save' in SaveFileDialog, the actual path for tempImg.Save become :

Path specified by SaveFileDialog + the relative path

automatically.

Thus if the path does not exist, this error occurs.

Thanks every one for the answers.

Cardinal answered 5/5, 2011 at 9:30 Comment(3)
I forgot to ensure that my directory existed, and got this same error. Thanks for sharing!Fay
Thanks for this useful tip. I am checked directory exists. It's ok. ;)Kaolack
yep, i had this issue, my problem was that I was creating dynamic file path and had to Trim() my variablesBay
O
21

I also had once this problem- it happens because the bitmap locks and you can't save it( if you want I can find the exact explanation) so anyway a fix around is this: Create a new bitmap the size of the original bitmap you have- copy the original bitmap to the new created bitmap and then dispose the original bitmap and save the new one.

Bitmap bm3 = new Bitmap(bm2);

And then save.

Orsino answered 28/4, 2011 at 8:55 Comment(2)
thanks! I don't know about the author, but your solution worked for me!Antananarivo
Thanks, this definitely helped. however, I had to add a thread.sleep so it would give some time to the OS to free up any resources. I don't know why.Terpsichore
N
5

This is usually an indicator that something else, potentially some other thread in your own application, already has the target file that you're trying to save locked at the file system level. If you look at the inner exception I believe it should mention this. If it's not directly in the InnerException Another way to confirm this (or discover what it might really be instead) is to turn on first chance exceptions in the debugger and watch for what exception is being thrown "underneath" Save and then being turned into this generic exception.

Neutral answered 28/4, 2011 at 5:1 Comment(4)
the tempImg is not used anywhere in the code and the inner exception says: A first chance exception of type 'System.Runtime.InteropServices.ExternalException' occurred in System.Drawing.dllCardinal
This is most likely the case, take a look at Microsoft common practice of working with GDI+Safelight
ExternalException has an HResult/ErrorCode property. Can you tell us what the value of that property is? That should lead us to the exact native problem GDI+ is having.Neutral
Yes, GDI+ seems single-threaded, I had an error on trying to save System.Drawing.Image loaded in another thread. Fix is saving new Bitmap(originalImage)Moberg
F
5

Tried all the solutions given here, but in vain. Found the solution eventually.

  1. Dispose any Graphics applied on image: g.dispose();
  2. Make sure save path exists: System.IO.Directory.Exists(dir);
Furgeson answered 15/8, 2012 at 1:26 Comment(0)
R
1

Is this an ASP.NET application?

A Generic Error occured at GDI+ in asp.net mostly because of missing target folder / access permissions.

Also your code could be simplified to :

       using (Image image= dataObject.GetImage())
       {
            if (image != null)
            {
                image.Save("test.bmp");
            }
        }
Ruelas answered 28/4, 2011 at 5:28 Comment(1)
There is no problem with permissions, as the procedure goes well in all the cases except one case as I have mentioned. ThanksCardinal
M
1

In my case it was an ASP.NET application in which I replaced a single DLL, and I had to simply re-start the application pool after deployment. Then it worked fine.

Mayst answered 19/8, 2016 at 7:15 Comment(1)
This drove me mad, tried everything that other posts where saying code was working fine one day and then all of a sudden it stopped leaving us with this gdi+ error. IIS was restarted the day before the issue but the application pool was not. after restarting the app pool all is good Thanks Fabian.Trin
S
0

This is code sample from Microsoft Forums.

// new image with transparent Alpha layer
using (var bitmap = new Bitmap(330, 18, PixelFormat.Format32bppArgb))
{
    using (var graphics = Graphics.FromImage(bitmap))
    {
        // add some anti-aliasing
        graphics.SmoothingMode = SmoothingMode.AntiAlias;

        using (var font = new Font("Arial", 14.0f, GraphicsUnit.Pixel))
        {
            using (var brush = new SolidBrush(Color.White))
            {
                // draw it
                graphics.DrawString(user.Email, font, brush, 0, 0);
            }
        }
    }

    // setup the response
    Response.Clear();
    Response.ContentType = "image/png";
    Response.BufferOutput = true;

    // write it to the output stream
    bitmap.Save(Response.OutputStream, ImageFormat.Png);
    Response.Flush();
}
Safelight answered 28/4, 2011 at 6:37 Comment(0)
S
0

I am trying to save image from resource and it gives me too GDI error when I directly use the method Bitmap.Save(filepath). I think We can use the same below code for any other bitmap image by cloning it.

Private void SaveResourceImage() {
    object resBmpObject = Resource.Image1.Clone();//Bitmap Image from resource file
    //object resBmpObject = anyBmpImage.clone(); //for image other than resource image
    Bitmap resBmpImage = (Bitmap)resBmpObject;
    resBmpImage.Save(destFilePath, System.Drawing.Imaging.ImageFormat.Png);
    resBmpImage.dispose();
}
Sounding answered 30/6, 2013 at 19:23 Comment(0)
I
0

Dispose your bitMap object after save image:

 bitMap.Dispose()
 oimg.Dispose()

 bitMap = Nothing
 oimg = Nothing
Inefficacy answered 19/5, 2015 at 9:15 Comment(0)
A
0

In my case, i was saving the bitmap file on the same location as the source, So that's the problem. I save the bitmap to the new location and all fine now.

Associationism answered 21/1, 2017 at 20:42 Comment(0)
X
0

I was facing the same issue, by changing image type ".bmp" to ".png" its work form me

Xanthochroism answered 27/6, 2017 at 3:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.