Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fixing "Generic error occurred in GDI+" while generating a Barcode

I am writing a barcode generator in C# I can generate barcodes as bitmaps and can show them in a Picturebox(WindowsForms). On the other hand I could not save my barcode as a gif or jpeg file. My barcode is a bitmap file and here is my code

Bitmap barCode = CreateBarCode("*"+txtBarCodeStr.Text+"*");
barCode.Save(@"C:\barcode.gif", ImageFormat.gif);
picBox.Image = barCode;            
MessageBox.Show("Created");

I get the following exception; A generic error occurred in GDI+.

like image 998
boraer Avatar asked Jul 22 '10 11:07

boraer


People also ask

How do you fix a generic error occurred in GDI in VB net?

Solution 1 So, you have two options: 1) Keep the stream open for the life of the image. 2) Copy the image to another and Dispose of the original stream and image once you have done that. You can now close and dispose the original stream and image.

What is generic error in C#?

If you get A generic error occurred in GDI+ in C#, it could be due to the bitmap image file you are trying to save already existing on your system drive. In this case, you can verify that the destination folder exists and that there isn't already a file with the same name in the destination folder.


2 Answers

Note: the title is misleading since no problem relating to creating BarCodes is described, instead it is about saving images/bitmaps. I can only assume Mr Puthiyedath, the bounty provider, is having the same error since no further information is provided.


The generic error occurred in GDI+ problem usually means one of two things:
A) You are trying to write to a file which already has a bitmap image open on it. From MSDN:

Saving the image to the same file it was constructed from is not allowed and throws an exception.

So, if you have a bitmap elsewhere in the app created from a file, you cannot save back to that same file until the bitmap is disposed. The obvious solution is to create a new bitmap and save it.

B) You may not have access to the folder/file

This is the more likely problem because performing File IO to a file in the root folder of the boot drive (as in the sample code by the OP), may be disallowed depending on the OS, security settings, permissions etc etc etc.

In the code below, if I try to save to "C:\ziggybarcode.gif" rather than the\Temp folder, nothing happens. There is no exception but no image is created either. Under different conditions an exception can result, but often these seem to be reported as the Generic Error. Solution: Don't use the root folder for files. Users\USERNAME\... is intended for just this purpose.

C) The folder/file name may not be legal

If the filename is contrived in code, it may be that the file or path is illegal. Test this using a literal, legal path such as @"C:\Temp\mybarcode.gif" (omit the @ for VB).

Use Path.Combine() to construct a legal path; and be sure the filename does not contain illegal characters.


One other exception which sometimes comes up, and may be of interest, is Out Of Memory Exception. This usually means there is a problem with the image format. I have a couple of apps that do a lot of work on images and found it was problematic tracking the format or assuming that an image can be saved to a particular format on any given machine. A BarCode generator might have a similar issue.

For simple apps or ones which only deal with a single, standard format, the simple Bitmap.Save method will often be fine:

myBmp.Save(@"C:\Temp\mybarcode.gif", ImageFormat.Gif);

But when your app is juggling different formats, it might be better to explicitly encode the image:

public static bool SaveImageFile(string fileName, ImageFormat format, Image img, 
              Int64 quality)
{
    ImageCodecInfo codec = GetEncoder(format);
    EncoderParameter qParam = new EncoderParameter(Encoder.Quality, quality);

    EncoderParameters encoderParams = new EncoderParameters(1);
    encoderParams.Param[0] = qParam;
    try
    {
        img.Save(fileName, codec, encoderParams);
        return true;
    }
    catch
    {
        return false;
    }
}

private static ImageCodecInfo GetEncoder(ImageFormat format)
{
    var codecs = ImageCodecInfo.GetImageDecoders();
    foreach (var codec in codecs)
    {
        if (codec.FormatID == format.Guid)
        {
            return codec;
        }
    }
    return null;
}

Put them in a DLL or make them extensions, and they become equally simple to work with:

SaveImageFile(@"c:\Temp\myBarCode.gif",
                  ImageFormat.Gif, myBmp, 100);

Particularly when working with JPGs, it becomes especially easy to manage the compression/quality parameter. I am not saying this is the preferred method, just that I have had far fewer problems in complex apps by explicitly encoding images.

Test code to create a BarCode GIF:

private void button1_Click(object sender, EventArgs e)
{
    Bitmap bmp = CreateBarcode("Ziggy12345");
    this.pb.Image = bmp;

    try { 
    // save to root of boot drive
    // does nothing on my system: no Error, No File
     bmp.Save(@"C:\zBarCodeDIRECT.gif", ImageFormat.Gif);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }

    // save BMP to file
    SaveImageFile(@"c:\Temp\zBarCodeBITMAP.gif",
                      ImageFormat.Gif, bmp, 100);

    // save PicBox image
    SaveImageFile(@"c:\Temp\zBarCodePICBOX.gif",
                ImageFormat.Gif, this.pb.Image, 100);

    // Try to save to same file while a bmp is open on it
    Bitmap myBmp = (Bitmap)Image.FromFile(@"c:\Temp\zBarCodeBITMAP.gif");
    // A generic Error in GDI
    myBmp.Save(@"c:\Temp\zBarCodeBITMAP.gif", ImageFormat.Gif);
}

The last one fails with the Generic GDI error even though it seems like it should be an IO or UnAuthorizedAccess related exception.

Output:

enter image description hereenter image description here

The first and last images do not save for the reasons explained above and in code comments.

like image 196
Ňɏssa Pøngjǣrdenlarp Avatar answered Nov 14 '22 22:11

Ňɏssa Pøngjǣrdenlarp


I had this problem before, and I was able to solve it using an intermediate bitmap object, something like this:

Bitmap barCode = CreateBarCode("*"+txtBarCodeStr.Text+"*");

//Use an intermediate bitmap object
Bitmap bm = new Bitmap(barCode);

bm.Save(@"C:\barcode.gif", ImageFormat.gif);
picBox.Image = barCode;            
MessageBox.Show("Created");

I found this solution/workaround here

The reason is because "You are trying to write to a file which already has a bitmap image open on it" as @Plutonix mentioned before.

like image 28
Rolo Avatar answered Nov 14 '22 22:11

Rolo