2013-07-11 55 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