在生成条形码时修复"GDI +中发生了一般错误"

bor*_*aer 8 .net c# image barcode winforms

我在C#中编写条形码生成器我可以生成条形码作为位图,并可以在Picturebox(WindowsForms)中显示它们.另一方面,我无法将条形码保存为gif或jpeg文件.我的条形码是位图文件,这是我的代码

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

我得到以下异常; GDI +中发生了一般错误.

Ňɏs*_*arp 5

注意:标题具有误导性,因为没有描述与创建条形码有关的问题,而是描述了保存图像/位图.我只能假设赏金提供者Puthiyedath先生有同样的错误,因为没有提供进一步的信息.


generic error occurred in GDI+问题通常是指两种情况之一:
A)你试图写它已经有一个位图图像就可以打开的文件. 来自MSDN:

不允许将图像保存到它构造的同一文件中并引发异常.

因此,如果您在从文件创建的应用程序中的其他位置有位图,则在放置位图之前无法保存回该文件.显而易见的解决方案是创建一个新的位图并保存它.

B)您可能无权访问文件夹/文件

这是更可能的问题,因为根据操作系统,安全设置,权限等等,可能不允许对引导驱动器的根文件夹中的文件执行文件IO(如OP的示例代码中所示).

在下面的代码中,如果我尝试保存到"C:\ziggybarcode.gif"而不是\Temp文件夹,则没有任何反应.没有例外,但也没有创建图像.在不同的条件下可能会导致异常,但通常会将这些异常报告为通用错误. 解决方案:不要将根文件夹用于文件. Users\USERNAME\...仅用于此目的.

C)文件夹/文件名可能不合法

如果文件名是在代码中设计的,则可能是文件或路径是非法的.使用文字的合法路径进行测试,例如@"C:\Temp\mybarcode.gif"(省略@for VB).

使用Path.Combine()构建一个法律路径; 并确保文件名不包含非法字符.


有时出现的另一个例外是可能感兴趣的是Out Of Memory Exception.这通常意味着图像格式存在问题.我有几个应用程序在图像上做了很多工作,发现跟踪格式或假设图像可以保存到任何给定机器上的特定格式是有问题的.BarCode生成器可能有类似的问题.

对于简单的应用程序或只处理单一标准格式的应用程序,简单的Bitmap.Save方法通常会很好:

myBmp.Save(@"C:\Temp\mybarcode.gif", ImageFormat.Gif);
Run Code Online (Sandbox Code Playgroud)

但是当你的应用程序处理不同的格式时,显式编码图像可能会更好:

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;
}
Run Code Online (Sandbox Code Playgroud)

将它们放入DLL或进行扩展,它们变得同样简单:

SaveImageFile(@"c:\Temp\myBarCode.gif",
                  ImageFormat.Gif, myBmp, 100);
Run Code Online (Sandbox Code Playgroud)

特别是在使用JPG时,管理压缩/质量参数变得特别容易.我并不是说这是首选方法,只是通过显式编码图像,在复杂应用程序中遇到的问题要少得多.

测试代码以创建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);
}
Run Code Online (Sandbox Code Playgroud)

Generic GDI error尽管看起来它应该是IO或UnAuthorizedAccess相关的异常,但最后一个失败了.

输出:

在此输入图像描述在此输入图像描述

由于上述原因和代码注释中的原因,第一张和最后一张图像无法保存.


lep*_*pie 0

Gif 是一种索引调色板格式。

将其保存为用于创建Bitmap实例的兼容格式。