2013-07-11 60 views
4

我有一個ASPX頁面,它將查詢字符串中的任何內容呈現爲垂直文本並返回一個PNG。它效果很好。Intermittent System.Drawing/GDI +「Generic」Error

我剛好有一位遇到問題的客戶。每隔幾天,頁面停止工作,並引發可怕的GDI +「通用」錯誤。

Error: System.Runtime.InteropServices.ExternalException (0x80004005): A generic error occurred in GDI+. 
at System.Drawing.Image.Save(Stream stream, ImageCodecInfo encoder, EncoderParameters encoderParams) 
at System.Drawing.Image.Save(Stream stream, ImageFormat format) 
... 

我不知道爲什麼會出現錯誤,或者爲什麼最終會消失。我能夠將一個測試ASPX文件放入他們的安裝中,運行類似的代碼並進行了一些修改,以查看我是否可以找出問題所在。我發現如果我將ImageFormat從Png更改爲Jpeg,錯誤就消失了。

我可以想象將產品更改爲呈現JPEG而不是PNG。然而,我無法知道這是否最終會像現在一樣間歇性地引發錯誤。

有人知道什麼可能會導致這樣的問題?謝謝!代碼如下。

更新:客戶服務器是運行IIS 7.5的Windows Server 2008 R2框,我的應用程序在.NET 4.0上運行。

protected void Page_Load(object sender, EventArgs e) 
    { 
     byte[] image = GetImageBytes(this.Text); 
     if (image != null) 
     { 
      Response.ClearContent(); 
      Response.ClearHeaders(); 
      Response.ContentType = "image/png"; 
      Response.OutputStream.Write(image, 0, image.Length); 
     } 
    } 

    private byte[] GetImageBytes(string text) 
    { 
     var font = new Font("Tahoma", 11, FontStyle.Bold, GraphicsUnit.Pixel); 

     // Create an image the size of the text we are writing 
     Bitmap img = new Bitmap(1,1); 
     var graphics = Graphics.FromImage(img); 
     int width = (int)graphics.MeasureString(text, font).Width; 
     int height = (int)graphics.MeasureString(text, font).Height; 
     img = new Bitmap(img, new Size(width, height)); 

     // Draw the text onto the image 
     graphics = Graphics.FromImage(img); 
     graphics.Clear(Color.Transparent); 
     graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; 
     graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; 
     graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; 
     graphics.DrawString(text, font, new SolidBrush(Color.Black), 0, 0); 
     graphics.Flush(); 

     // Rotate the image to be vertical 
     img.RotateFlip(RotateFlipType.Rotate270FlipNone); 

     var stream = new System.IO.MemoryStream(); 
     img.Save(stream, ImageFormat.Png); 
     stream.Position = 0; 
     return stream.ToArray(); 
    } 
+1

這可能是一個有問題的圖形卡驅動程序。檢查是否已用完桌面堆。如果它已滿,則將事件日誌條目寫入系統事件日誌中。檢查應用程序和系統事件日誌中是否有可疑事件。 –

+1

你可能應該放置字體,img,圖形和流對象。 – LarsTech

+0

@LarsTech,真的,這就是爲什麼在我的答案我建議新的代碼:) – Fredou

回答

3

I would say that the flush could be the issue

強制所有未決的圖形操作的執行,並立即返回,而無需等待操作完成。

此成員已被超載。有關此成員的完整信息(包括語法,用法和示例),請單擊重載列表中的名稱。

你可以試試看看你是否仍然有這個問題?

private byte[] GetImageBytes(string text) 
    { 
     using (var font = new Font("Tahoma", 20, FontStyle.Bold, GraphicsUnit.Pixel)) 
     using (var img = new Bitmap(1, 1)) 
     { 
      int width; 
      int height; 
      using (var graphics = Graphics.FromImage(img)) 
      { 
       width = (int)graphics.MeasureString(text, font).Width; 
       height = (int)graphics.MeasureString(text, font).Height; 
      } 
      using (var realImg = new Bitmap(img, new Size(width, height))) 
      { 
       using (var graphics = Graphics.FromImage(realImg)) 
       { 
        graphics.Clear(Color.Transparent); 
        graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; 
        graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; 
        graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; 
        graphics.DrawString(text, font, new SolidBrush(Color.Black), 0, 0); 
       } 

       realImg.RotateFlip(RotateFlipType.Rotate270FlipNone); 

       using (var stream = new System.IO.MemoryStream()) 
       { 
        realImg.Save(stream, System.Drawing.Imaging.ImageFormat.Png); 
        stream.Position = 0; 
        return stream.ToArray(); 
       } 
      } 
     } 
    } 
+0

Fredou - 我在一個流程中使用了一個控制檯應用程序來運行代碼數百萬次,並且我沒有遇到任何問題。然而,這看起來好像是對代碼做出的一個很好的改變。謝謝! –

+0

不好意思,剛纔注意到你也把使用語句和flush一起去掉了。我會試試這個。 –

+0

@BarryFandango,是的,我刪除了它,因爲我沒有看到這個刷新調用的需要,我也更新了我的代碼,因爲我忘記了在圖形上使用 – Fredou