ASP.NET 2.0编程技巧之用Response对象输出图像

[转]http://tech.it168.com/n/2007-01-05/200701051456653_3.shtml

一、 简介

作为ASP.NET基本对象之一的Response对象不但可以通过Write()方法直接在页面上输出字符串数据,而且还可以使用BinaryWrite()方法直接显示二进制表示的数据,如图像、图片等。

本文示例小工程将向你展示如何使用Response对象在ASP.NET 2.0 Web页面中输出直接存储在SQL Server 2005数据库中的图像数据。

【注意】在本例中,我们没有讨论仅在SQL Server 2005表格中存储图像的URL的情形。因为这种情形是实际开发中被广为采用的方法,所以,读者不难在Web上搜到相应的使用案例。

首先,让我们来分析一个简单的直接在Web页面上绘制并输出图像数据的例子。

二、 直接在Web页面上绘制并输出图像数据

下面的代码示例在请求页面时将绘制三个部分重叠的矩形。该代码首先将ContentType属性设置为image/jpeg,以便将整个页面呈现为一幅 JPEG图像。第二步,该代码调用Clear方法以确保不会将无关的内容(包括标头)与此响应一同发送。第三步,该代码将BufferOutput属性设 置为true,从而使该页面在完全处理之后再发送到发出请求的客户端。第四步,创建两个用于绘制矩形的对象,即Bitmap和Graphics对象。在该 页中创建的变量将作为绘制矩形的坐标和在最大的矩形中显示的字符串。

在绘制三个矩形和其中显示的字符串时,将Bitmap保存到与 OutputStream属性相关联的Stream对象中,并将其格式设置为JPEG。接下来,该代码调用Dispose和Dispose方法来释放资源 —这些资源为两个绘制对象所使用。最后,该代码调用Flush方法将缓冲的响应发送到请求客户端。

完整的实现代码如下所示:

<%@ Page Language="C#" %>

<%@ import Namespace="System.Drawing" %>

<%@ import Namespace="System.Drawing.Imaging" %>

<%@ import Namespace="System.Drawing.Drawing2D" %>

<script runat="server">

private void Page_Load(object sender, EventArgs e)

...{

//设置页面的content type为JPEG文件

//并且清除所有的响应头部信息

Response.ContentType = "image/jpeg";

Response.Clear();

//对响应作出缓冲以便处理完成后发送页面

Response.BufferOutput = true;

//创建一字体风格

Font rectangleFont = new Font(

"Arial", 10, FontStyle.Bold);

//创建整数变量

int height = 100;

int width = 200;

//创建一个随机数字生成器并且基于它创建

//变量值

Random r = new Random();

int x = r.Next(75);

int a = r.Next(155);

int x1 = r.Next(100);

//创建一张位图并且使用它创建一个

//Graphics对象

Bitmap bmp = new Bitmap(

width, height, PixelFormat.Format24bppRgb);

Graphics g = Graphics.FromImage(bmp);

g.SmoothingMode = SmoothingMode.AntiAlias;

g.Clear(Color.LightGray);

//使用这个Graphics对象绘制3个矩形

g.DrawRectangle(Pens.White, 1, 1, width-3, height-3);

g.DrawRectangle(Pens.Aquamarine, 2, 2, width-3, height-3);

g.DrawRectangle(Pens.Black, 0, 0, width, height);

//使用这个Graphics对象输出一个字符串

// on the rectangles.

g.DrawString(

"ASP.NET Samples", rectangleFont,

SystemBrushes.WindowText, new PointF(10, 40));

//在其中两个矩形上添加颜色

g.FillRectangle(

new SolidBrush(

Color.FromArgb(a, 255, 128, 255)),

x, 20, 100, 50);

g.FillRectangle(

new LinearGradientBrush(

new Point(x, 10),

new Point(x1 + 75, 50 + 30),

Color.FromArgb(128, 0, 0, 128),

Color.FromArgb(255, 255, 255, 240)),

x1, 50, 75, 30);

//把位图保存到响应流中并且把它转换成JPEG格式

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

//释放掉Graphics对象和位图所使用的内存空间

g.Dispose();

bmp.Dispose();

//把输出结果发送到客户端

Response.Flush();

}

</script>

<html>

<head>

</head>

<body>

<form runat="server">

</form>

</body>

</html>

接下来,让我们讨论本文重点—如何在ASP页面中输出直接存储在数据库中的图像数据。

三、 事件设计

示例工程中的DispImage.aspx页面在其初始化函数Page_Load(object sender,EventArgs e)中使用Response对象输出一幅图像—该图像存储在SQL Server 2005 Express Edition数据库中,并用二进制表示。

在代码中,我们首先从数据库PictureDB的表格PictureTab中获取一个ID值为1的图片,然后使用byte数组Data保存图片的数据。然后,我们可以基于如下步骤来输出相应的图像:

1. 设置Response对象的输出类型;

2. 输出图像的文件头;

3. 输出图像的二进制数据;

4. 结束输出。如果图片太大,还可以使用输出缓冲的方法。

函数Page_Load(object sender,EventArgs e)的程序代码如下:

1protected void Page_Load(object sender,EventArgs e)

2...{ /**////创建链接

3SqlConnection myConnection = new SqlConnection(

4ConfigurationManager.ConnectionStrings["SQLCONNECTIONSTRING"].ConnectionString);

5/**////定义SQL语句

6string cmdText = "SELECT * FROM PictureTab WHERE Picture";

7/**////创建Command

8SqlCommand myCommand = new SqlCommand(cmdText,myConnection);

9/**////定义DataReader

10SqlDataReader dr = null;

11try

12...{ /**////打开链接

13myConnection.Open();

14/**////读取数据

15dr = myCommand.ExecuteReader(CommandBehavior.CloseConnection);

16}

17catch(SqlException ex)

18...{ /**////抛出异常

19throw new Exception(ex.Message,ex);

20}

21/**////定义保存数据的字节数组

22byte[] Data = null;

23while(dr.Read())

24...{ /**////读取数据

25Data = (byte[])dr["Data"];

26Response.ContentType = dr["Type"].ToString();

27}

28dr.Close();

29//显示图片数据

30this.EnableViewState = false;

31/**////输出文件头

32Response.AppendHeader("Content-Length",Data.Length.ToString());

33/**////输出文件的数据

34Response.BinaryWrite(Data);

35/**////结束输出

36Response.End();

37}

四、 附注与小结

把上面的页面DispImage.aspx设置为初始页面,然后运行上面的示例工程。此时,页面上应该显示一张存储在数据库表格中的图片。

在实践中,有些情况下需要把图像数据直接存储在数据库中;而有些情况下只在数据库存储图像文件的URL而把实际图像文件存储在服务器文件系统中则更好。从 性能上看,将这种大型数据存储为文件肯定要快一些,而且图形人员能够更为容易地访问图像并对其编辑。然而,当需要在不同机器间移动数据库时,将这种大型数 据存储为文件就会面临最棘手的问题,因为文件很容易断开与数据库的连接。因此,如果将其直接存储在数据库中则明显可以使数据保持轻松的同步。总之,各有利 弊,需慎重做出选择。