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+.
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.
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.
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:
The first and last images do not save for the reasons explained above and in code comments.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With