Image.Save无法将PNG保存到HttpContext.Response的问题

  早些时候写的关于在MVC3中使用自定义的ImageResult来响应客户端对图片的请求,在一直以来都运行的很不错,但今天突然发现这个ImageResult碰到png图片就罢工,直接报500错误,查看具体的错误信息是:System.Runtime.InteropServices.ExternalException: A generic error occurred in GDI+,转成中文应该是:System.Runtime.InteropServices.ExternalException (0x80004005): GDI+ 中发生一般性错误。Image.Save神奇报错。

  具体代码如下:

public override void  ExecuteResult(ControllerContext context)
{
    // 代码很简单
    context.HttpContext.Response.ContentType = String.Format("image/{0}", Type);
    // 关键是这句,将图片流写入到Response响应流中.
    Image.Save(context.HttpContext.Response.OutputStream, Type);
}

  这个的作用就是将Image写入到Response的输出流中,在非PNG格式的时候,一切都是太平的。通过伟大的Google搜索,发现也有人碰到同样的问题 —— 怎么可能会没有呢,我肯定不是原创。发现了问题的所在是因为PNG图片的解码器需要一个bidirectional nature的stream ,bidirectional nature stream就是可双向查找的流,按这个说法,应该Image流不是bidirectional nature的。既然这样,那么我们要改成双向流应该就没有太大问题了,第一反应是改成MemoryStream。

public override void  ExecuteResult(ControllerContext context)
{
    using(MemoryStream ms = new MemoryStream()){
        Image.Save(ms, Type);
        context.HttpContext.Response.ContentType = String.Format("image/{0}", Type);
        ms.WriteTo(context.HttpContext.Response.OutputStream);
    }
}

  将代码重新编译部署,问题解决!看来还真是这个问题,保存下方法,以便其他碰到这个问题的朋友参考。

  由于Google习惯打开很多页面,没看完就解决了这个问题。后来在Scott Hanselman的中文博客里面看到这篇文章,也是解决这个问题的,有兴趣的可以参考下。当然,还有这篇BBS问答

Wednesday, November 14, 2012 | .NET技术

文章评论

No comments posted yet.

发表评论

Please add 6 and 4 and type the answer here:

关于博主

  一枚成分复杂的网络IT分子,属于互联网行业分类中的杂牌军。