boraer
boraer

Reputation: 419

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+.

Upvotes: 8

Views: 5210

Answers (6)

Fuad Alizade
Fuad Alizade

Reputation: 31

I found a simple solution for it:

  1. Create a folder in solution, for example, I created Template folder in solution(Inside the project).
  2. Then try to save your file into that folder with Server.MapPath, for example, Bitmap.Save(HttpContext.Current.Server.MapPath("/Template/3777.jpeg"), System.Drawing.Imaging.ImageFormat.Jpeg);
  3. And Finally return HttpContext.Current.Server.MapPath("/Template/3777.jpeg");
  4. For me it worked well and advantage of this method is the file that you want to save,not saving into the folder but when you return,it fetches the file

Upvotes: 0

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.

Upvotes: 5

Rolo
Rolo

Reputation: 3433

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.

Upvotes: 1

Shahzad Latif
Shahzad Latif

Reputation: 1424

You may try Aspose.BarCode for .NET as well. This component allows you to create bar codes from scratch and work with existing bar codes. It provides great flexibility to create a variety of bar code images. You can use it with any type of .NET application. Please try at your end and see if this might help in your scenario.

Disclosure: I work as a developer evangelist at Aspose.

Upvotes: 0

Ugene
Ugene

Reputation: 13

your problem is permissions. allow network service full access to the path you are saving the file and see if that helps

good luck!

Upvotes: 0

leppie
leppie

Reputation: 117280

Gif is an indexed pallete format.

Save it in a compatible format what was used to create the Bitmap instance.

Upvotes: 0

Related Questions