[英]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).我正在用 C# 编写条形码生成器我可以将条形码生成为位图,并可以在图片框(WindowsForms)中显示它们。 On the other hand I could not save my barcode as a gif or jpeg file.另一方面,我无法将条形码保存为 gif 或 jpeg 文件。 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+. GDI+ 中出现一般错误。
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.我只能假设赏金提供者 Puthiyedath 先生有同样的错误,因为没有提供进一步的信息。
The generic error occurred in GDI+
problem usually means one of two things: generic error occurred in GDI+
问题中generic error occurred in GDI+
的generic error occurred in GDI+
通常意味着以下两种情况之一:
A) You are trying to write to a file which already has a bitmap image open on it. A) 您正在尝试写入已打开位图图像的文件。 FromMSDN :从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 B) 您可能无权访问该文件夹/文件
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.这是更有可能出现的问题,因为根据操作系统、安全设置、权限等,可能不允许对引导驱动器根文件夹中的文件执行文件 IO(如 OP 的示例代码中所示)。
In the code below, if I try to save to "C:\\ziggybarcode.gif"
rather than the \\Temp
folder, nothing happens .在下面的代码中,如果我尝试保存到"C:\\ziggybarcode.gif"
而不是\\Temp
文件夹,则什么也不会发生。 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. Users\\USERNAME\\...
仅用于此目的。
C) The folder/file name may not be legal C) 文件夹/文件名可能不合法
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).使用文字、合法的路径(例如@"C:\\Temp\\mybarcode.gif"
(对于 VB,省略@
)来测试它。
Use Path.Combine()
to construct a legal path;使用Path.Combine()
构造合法路径; 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 .另一个有时会出现并且可能会引起兴趣的异常是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:对于简单的应用程序或仅处理单一标准格式的应用程序,简单的Bitmap.Save
方法通常会很好:
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:将它们放在 DLL 中或使它们扩展,它们变得同样易于使用:
SaveImageFile(@"c:\Temp\myBarCode.gif",
ImageFormat.Gif, myBmp, 100);
Particularly when working with JPGs, it becomes especially easy to manage the compression/quality parameter.特别是在处理 JPG 时,管理压缩/质量参数变得特别容易。 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:创建条码 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.最后一个失败并显示Generic GDI error
即使它看起来应该是 IO 或 UnAuthorizedAccess 相关异常。
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.原因是因为“您正在尝试写入一个已经打开了位图图像的文件”,正如前面提到的@Plutonix。
Gif is an indexed pallete format. Gif 是一种索引调色板格式。
Save it in a compatible format what was used to create the Bitmap
instance.将其保存为用于创建Bitmap
实例的兼容格式。
your problem is permissions.你的问题是权限。 allow network service full access to the path you are saving the file and see if that helps允许网络服务完全访问您保存文件的路径,看看是否有帮助
good luck!祝你好运!
I found a simple solution for it:我找到了一个简单的解决方案:
Bitmap.Save(HttpContext.Current.Server.MapPath("/Template/3777.jpeg"), System.Drawing.Imaging.ImageFormat.Jpeg);
然后尝试使用 Server.MapPath 将文件保存到该文件夹中,例如Bitmap.Save(HttpContext.Current.Server.MapPath("/Template/3777.jpeg"), System.Drawing.Imaging.ImageFormat.Jpeg);
HttpContext.Current.Server.MapPath("/Template/3777.jpeg");
最后返回HttpContext.Current.Server.MapPath("/Template/3777.jpeg");
You may try Aspose.BarCode for .NET as well.你也可以试试Aspose.BarCode for .NET 。 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.您可以将它用于任何类型的 .NET 应用程序。 Please try at your end and see if this might help in your scenario.请在你的最后尝试,看看这是否对你的场景有帮助。
Disclosure: I work as a developer evangelist at Aspose.披露:我在 Aspose 担任开发人员布道者。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.