簡體   English   中英

在生成條碼時修復“GDI+ 中發生一般錯誤”

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

我正在用 C# 編寫條形碼生成器我可以將條形碼生成為位圖,並可以在圖片框(WindowsForms)中顯示它們。 另一方面,我無法將條形碼保存為 gif 或 jpeg 文件。 我的條形碼是位圖文件,這是我的代碼

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

我得到以下異常; GDI+ 中出現一般錯誤。

注意:標題具有誤導性,因為沒有描述與創建條形碼相關的問題,而是關於保存圖像/位圖。 我只能假設賞金提供者 Puthiyedath 先生有同樣的錯誤,因為沒有提供進一步的信息。


generic error occurred in GDI+問題中generic error occurred in GDI+generic error occurred in GDI+通常意味着以下兩種情況之一:
A) 您正在嘗試寫入已打開位圖圖像的文件。 MSDN

不允許將圖像保存到構建它的同一文件中,並引發異常。

因此,如果您在應用程序的其他地方有從文件創建的位圖,則在位圖被釋放之前,您無法將其保存回同一個文件。 顯而易見的解決方案是創建一個新的位圖並保存它。

B) 您可能無權訪問該文件夾/文件

這是更有可能出現的問題,因為根據操作系統、安全設置、權限等,可能不允許對引導驅動器根文件夾中的文件執行文件 IO(如 OP 的示例代碼中所示)。

在下面的代碼中,如果我嘗試保存到"C:\\ziggybarcode.gif"而不是\\Temp文件夾,則什么也不會發生 也不例外,但也不會創建圖像。 在不同的條件下可能會導致異常,但通常這些似乎被報告為通用錯誤。 解決方案:不要將根文件夾用於文件。 Users\\USERNAME\\...僅用於此目的。

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

如果文件名在代碼中被人為設計,則可能是該文件或路徑是非法的。 使用文字、合法的路徑(例如@"C:\\Temp\\mybarcode.gif" (對於 VB,省略@ )來測試它。

使用Path.Combine()構造合法路徑; 並確保文件名不包含非法字符。


另一個有時會出現並且可能會引起興趣的異常Out Of Memory Exception 這通常意味着圖像格式有問題。 我有幾個應用程序在圖像上做了很多工作,但發現跟蹤格式或假設圖像可以在任何給定機器上保存為特定格式是有問題的。 條碼生成器可能有類似的問題。

對於簡單的應用程序或僅處理單一標准格式的應用程序,簡單的Bitmap.Save方法通常會很好:

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

但是當您的應用程序處理不同的格式時,最好對圖像進行顯式編碼:

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;
}

將它們放在 DLL 中或使它們擴展,它們變得同樣易於使用:

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

特別是在處理 JPG 時,管理壓縮/質量參數變得特別容易。 我並不是說這是首選方法,只是通過顯式編碼圖像在復雜應用程序中遇到的問題要少得多。

創建條碼 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);
}

最后一個失敗並顯示Generic GDI error即使它看起來應該是 IO 或 UnAuthorizedAccess 相關異常。

輸出:

在此處輸入圖片說明在此處輸入圖片說明

由於上述原因和代碼注釋中的原因,第一張和最后一張圖像不會保存。

我以前遇到過這個問題,我能夠使用中間位圖對象來解決它,如下所示:

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");

我在這里找到了這個解決方案/解決方法

原因是因為“您正在嘗試寫入一個已經打開了位圖圖像的文件”,正如前面提到的@Plutonix。

Gif 是一種索引調色板格式。

將其保存為用於創建Bitmap實例的兼容格式。

你的問題是權限。 允許網絡服務完全訪問您保存文件的路徑,看看是否有幫助

祝你好運!

我找到了一個簡單的解決方案:

  1. 在解決方案中創建一個文件夾,例如,我在解決方案(項目內部)中創建了模板文件夾。
  2. 然后嘗試使用 Server.MapPath 將文件保存到該文件夾​​中,例如Bitmap.Save(HttpContext.Current.Server.MapPath("/Template/3777.jpeg"), System.Drawing.Imaging.ImageFormat.Jpeg);
  3. 最后返回HttpContext.Current.Server.MapPath("/Template/3777.jpeg");
  4. 對我來說它運行良好,這種方法的優點是您要保存的文件,而不是保存到文件夾中,但是當您返回時,它會獲取文件

你也可以試試Aspose.BarCode for .NET 該組件允許您從頭開始創建條碼並使用現有條碼。 它為創建各種條碼圖像提供了極大的靈活性。 您可以將它用於任何類型的 .NET 應用程序。 請在你的最后嘗試,看看這是否對你的場景有幫助。

披露:我在 Aspose 擔任開發人員布道者。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM