使用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);


同样把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);

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

正确代码2:

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

ContractedBlock.gif ExpandedBlockStart.gif 代码
1 string  sIconFileName  =  Server.MapPath( " test.png " );
2 Bitmap bmp  =   new  Bitmap( 200 60 );
3 Graphics g  =  Graphics.FromImage(bmp);
4 g.Clear(Color.Transparent);
5 g.DrawEllipse( new  Pen( new  SolidBrush(Color.Blue)),  10 10 180 40 );
6 Response.ClearContent();
7 Response.ContentType  =   " image/png " ;
8 bmp.Save(sIconFileName, ImageFormat.Png); 

 

原因剖析:

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

 

转载于:https://www.cnblogs.com/mingle/archive/2009/11/27/donet-drawing.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值