使用GDI+绘制Png图像的尴尬

问题场景:

看了衣志明的WebCast(三)中有使用GDI+绘图部分,跟着写了代码,居然报错了":

“System.Runtime.InteropServices.ExternalException: A generic error occurred in GDI+.”

定位的代码行为:

bmp.Save(Response.OutputStream, ImageFormat.Png);

开发环境:

1、WindowsXP,vs2005,vs2008,vs2010beta2;

2、Windows2003,vs2005,vs2008,vs2010beta2

代码剖析:

需求:建立web应用程序,运行起始页输出一个椭圆。

放置在Page_Load中的代码

出错的代码:

代码
Bitmap bmp = new Bitmap(20060);
Graphics g 
= Graphics.FromImage(bmp);
g.Clear(Color.White);
g.DrawEllipse(
new Pen(new SolidBrush(Color.Blue)), 101018040);
Response.ClearContent();
Response.ContentType 
= "image/png";
bmp.Save(Response.OutputStream, ImageFormat.Png);


同样把png换成gif或者jpeg,程序正常运行。

正确的代码1:(更新的代码行:1、8、9)

借助MemStream输出图片

代码
1 MemoryStream MemStream = new MemoryStream();
2 Bitmap bmp = new Bitmap(20060);
3 Graphics g = Graphics.FromImage(bmp);
4 g.Clear(Color.White);
5 g.DrawEllipse(new Pen(new SolidBrush(Color.Blue)), 101018040);
6 Response.ClearContent();
7 Response.ContentType = "image/png";
8 bmp.Save(MemStream, ImageFormat.Png);         
9 MemStream.WriteTo(Response.OutputStream);

其中第9行代码可更换为:         Response.BinaryWrite(MemStream.ToArray());

正确代码2:

指定图片的存放位置来进行保存

代码

 

原因剖析:

png是个特例。它的解码器需要双向流。所以我们首先需要把流读取到内存流,然后使用输出流写出内存流。

gif的解码器内置了并行机制来处理。

延伸阅读:

http://www.west-wind.com/Weblog/posts/6008.aspx

http://www.evolt.org/article/To_PNG_or_not_to_PNG/22/60134/index.html

 

posted @ 2009-11-27 23:57  风影极光  阅读(3814)  评论(10编辑  收藏  举报