使用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(200, 60);
Graphics g = Graphics.FromImage(bmp);
g.Clear(Color.White);
g.DrawEllipse(new Pen(new SolidBrush(Color.Blue)), 10, 10, 180, 40);
Response.ClearContent();
Response.ContentType = "image/png";
bmp.Save(Response.OutputStream, ImageFormat.Png);
Graphics g = Graphics.FromImage(bmp);
g.Clear(Color.White);
g.DrawEllipse(new Pen(new SolidBrush(Color.Blue)), 10, 10, 180, 40);
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(200, 60);
3 Graphics g = Graphics.FromImage(bmp);
4 g.Clear(Color.White);
5 g.DrawEllipse(new Pen(new SolidBrush(Color.Blue)), 10, 10, 180, 40);
6 Response.ClearContent();
7 Response.ContentType = "image/png";
8 bmp.Save(MemStream, ImageFormat.Png);
9 MemStream.WriteTo(Response.OutputStream);
2 Bitmap bmp = new Bitmap(200, 60);
3 Graphics g = Graphics.FromImage(bmp);
4 g.Clear(Color.White);
5 g.DrawEllipse(new Pen(new SolidBrush(Color.Blue)), 10, 10, 180, 40);
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