asp读取mysql图片显示,在Asp.net中图片存储、读取、显示通用方法详解

前端碰到对在一个系统遇到流程控制中需要存储在数据库存储一个签名图片的问题-一直控制不好, 今天特别关于这个问题详细看了一下.其实这个问题网上资源还是相当多的,但问题是过于凌乱 资料残缺不全 甚至我感觉其中有相当的一部分会对读者产生一些误导.对于Asp.net中存储图片我在08年一月份就做了一个详细解决方案,今天在这个基础主要对一些细节控制上以及页面显示上做了完善,详细步骤如下:

首先声明一下开发环境:VS2008+SQL2005数据库+.NET FrameWork 3.5版本

(1)存储图片ImageStore表数据库设计:

1 createtableStoreImage2(3 idintnotnullidentity(1,1)primarykey,4 marknamevarchar(100)notnull,--图片备注名称5 markContentimagenotnull,--文件内容6 markTypevarchar(100)notnull,--保存文件类型 用于生成7 markSizeintnotnull,--图片长度 读取数据用8 markLinkUrlvarchar(1000)notnull,--数据库路径9 markDatedatetimenotnulldefault(getdate())--上传时间10)11 go

其中在表中设计中添加了上传图片文件类型和文件大小(Byte[]字节大小),主要为了读取时对图片显示进行控制.请参考后面编码说明.存储图片内容采用Image类型,SQL2005数据容量为2G,对应C#中类型Byte[](字节数组),其中在设计中我还参考使用SQL中Binary类型,但是测试后发现Binary类型容量范围1-8000字节,对于图片容量太小, markLinkUrl为了测试以图片路径方式存储并读取显示在页面这种方式 请参考后面详细说明.

(2)图片存储到数据库并单一读取:

图片存储:通过文件上传获取图片并转换成Byte[]字节数组,保存到数据库Image字段,页面设计如下:

20088602_1.gif

20088602_2.gif代码

1 2 34 备 注:5 上 传:6 78 9 functioncheckClint()10{11 vargetmarkname=document.getElementById("markname");12 vargetfile=document.getElementById("FileUpload1");1314 if(getmarkname.value=="")15{16 alert('请输入图片备注名称!');17getmarkname.focus();18 returnfalse;19 }elseif(getfile.value=="")20{21 alert('请选择上传文件路径!');22getfile.focus();23 returnfalse;24 }else25{26 returntrue;27}28}29 30      31 3233       34 35      36 37        38 39 
40 
41 42 
43 图片路径方式读取:
44 服务器端:45 
46 47 
48 客户端Img:49 
50 51 

在页面From表单添加了一个属性-在页面Form中设置属性enctype -设置或获取表单的 MIME 编码

单一保存文件到数据库通用方法【注明:通用方法写在Button1_Click事件中-命名没有修改主要为了功能】 通用方法如下:

20088602_1.gif

20088602_2.gif代码

1 ///2 ///上传文件同时并保存到数据中统一3 ///Author:chenkai Date:2010年2月2日16:24:294 ///5 protectedvoidButton1_Click(objectsender, EventArgs e)6{7 //获取数据8 stringgetname=this.markname.Text;9 stringgetfile=this.FileUpload1.PostedFile.FileName;1011 //上传文件12 stringgetlastpath=FileUploadCompant(this.FileUpload1);1314 //获取上传文件流15 byte[] getbyte=newbyte[this.FileUpload1.PostedFile.ContentLength];16 Stream filestream=this.FileUpload1.PostedFile.InputStream;1718 //读入数据19 filestream.Read(getbyte,0,this.FileUpload1.PostedFile.ContentLength);2021 //插入数据22 #region23 stringsql="insert into StoreImage(markname,markContent,markType,markSize,markLinkUrl) values(@name,@content,@type,@size,@link)";2425 SqlParameter[] getpars=newSqlParameter[5];26 getpars[0]=newSqlParameter("@name", getname);27 getpars[1]=newSqlParameter("@content", getbyte);//文件内容插入This.Fileupload1.FileBytes同样可以直接转换成Byte数组不用转换28 getpars[2]=newSqlParameter("@type",this.FileUpload1.PostedFile.ContentType);//保存文件类型29 getpars[3]=newSqlParameter("@size",this.FileUpload1.PostedFile.ContentLength);//文件长度30 getpars[4]=newSqlParameter("@link", getlastpath);3132 intgetrescount=DBUtility.SqlHelper.ExecuteNonQuery(DBUtility.SqlHelper.connString,CommandType.Text,sql,getpars);3334 if(getrescount==1)35{36 //添加成功37 ScriptManager.RegisterStartupScript(this.Page,this.GetType(),"aler","alert( '图片记录成功添加到数据库');",true);38}39 else40{41 //添加失败42 ScriptManager.RegisterStartupScript(this.Page,this.GetType(),"aler","alert( '图片记录添加失败');",true);43}4445 #endregion46 }

这种获得图片转换成Byte【】字节数组通用,注意:其中在Fileupload控件中有个GetBytes属性:This.Fileupload1.FileBytes可以直接把上传内容转换成字节数组而不必通过文件流来读取上传文件内容,这种方式更为快捷;如上图片成功保存到数据库 接下来就是如何读取和显示控制的问题:

(3)数据库存储图片的读取和显示控制:

从数据库中读取到字节流后把图片直接写入页面并对显示进行控制 读取方法如下【该方法下载Button2_Click中】:

20088602_1.gif

20088602_2.gif代码

1 ///2 ///读取数据库中图片并显示出来3 ///Author:chenkai Date:2010年2月2日16:48:184 ///5 protectedvoidButton2_Click(objectsender, EventArgs e)6{7 //获得数据8 stringsql="select * from StoreImage order by id desc";910 #region11 using(SqlDataReader getreader=DBUtility.SqlHelper.ExecuteReader(DBUtility.SqlHelper.connString, CommandType.Text, sql))12{13 if(getreader!=null&&getreader.HasRows)14{15 //读取数据16 while(getreader.Read())17{18 Response.ContentType=getreader["markType"]asstring;19 Response.OutputStream.Write(getreader["markContent"]asbyte[],0, Convert.ToInt32(getreader["markSize"].ToString()));20Response.End();21}22}23}24 #endregion25 }

数据库中MarkType字段用来设置请求回发页面内容类型,获得字节流后把回发内容转换成输出流然后输出到当前页面,当然也可以直接使用Response.BinaryWrite()写入页面,图片自动显示.但是有人会说我想把它显示在页面一个Image控件中或是放到一个DIV层中这样实际需求. 这就是在实际需求对读取图片进行显示控制问题. 制作过验证码图片应该知道,验证码生成图片单独放在一个页面让后通过Image控件的ImageUrl来链接该页面,即可实现在Image控件控制,同理这种方式也是适用的: -添加了一个页面用来存储生成图片,详细代码如下:OutPutImageDemo页面后台编码:

20088602_1.gif

20088602_2.gif代码

1 //PageLoad事件中加载图片 并显示到OutPutImageDemo页面2 //Author:陈凯 Date:2010年2月3日10:28:173 protectedvoidPage_Load(objectsender, EventArgs e)4{5 if(!IsPostBack)6{7 //获得数据8 stringsql="select * from StoreImage order by id desc";910 #region11 using(SqlDataReader getreader=DBUtility.SqlHelper.ExecuteReader(DBUtility.SqlHelper.connString, CommandType.Text, sql))12{13 if(getreader!=null&&getreader.HasRows)14{15 //读取数据16 while(getreader.Read())17{18 Response.ContentType=getreader["markType"]asstring;19 Response.OutputStream.Write(getreader["markContent"]asbyte[],0, Convert.ToInt32(getreader["markSize"].ToString()));20Response.End();21}22}23}24 #endregion25}26 }

那么在TestImageStoreToDB.aspx页面中一个控件中获取该图片 只需设置图片的链接路径即可 代码如下:

1 this.Image1.ImageUrl="OutPutImageDemo.aspx";//链接输出图片页面即可

(4)数据库存储图片路径方式:

直接在数据库存储图片对资源图片较多, 图片文件较大 类似银行内部系统中对VIP用户签名就是用签名图片方式存储的 这主要为了安全上考虑,实际需求中使用次数频繁 且常常更新 无疑中这种使数据库中数据显得有些臃肿 数据容量增大,同时也增加了访问数据库服务器的负载,而使用存储图片路径的方式:图片文件放在服务器硬盘上,数据库中只需一个文件路径指向硬盘上图片文件即可 存储方式相比存储字节流要简单容易控制 但是我在网上发现关于这种页面显示的诸多问题如下我说明一下再Asp.net对图片页面显示控制:

数据库中存储路径为绝对路径: 截图如下

20088602_3.gif

现在页面放一个服务器端的Image控件和Html中的来验证. 如果直接用绝对路径对控件进行赋值 页面并不显示.其实这就涉及到.net中绝对路径,相对路径和虚拟路径三者之间转换的问题:

绝对路径是不行的,在硬盘上存储文件命名是唯一的同时不会存在不同的文件格式相同的命名情况,过滤绝对路径,从绝对路径就能看出图片的存储位置就在根目录下FileuploadDict文件夹下,我们只需把这个绝对路径转换成程序可用相对路径即可: 同时我们用服务器端的Image控件和Html测试一下结果:

1 //getfilepath是获得数据中图片存储路径(markLinkUrl字段)数据2 if(!string.IsNullOrEmpty(getfilepath))3{4 //截取当前图片文件名5 stringgetclintpath=getfilepath.Substring(getfilepath.LastIndexOf('\\'));67 //路径~/ 仅对 ASP.NET  的服务器控件起作用  ~/ 的意思是相对站点的虚拟根路径8 //“~”表示的路径是当前应用程序的跟目录。“~”和上面介绍的“/”最大的区别是由服务器进行动态解释9 getclintpath=@"~\FileuploadDict"+getclintpath;//拼接成客户端服务器端路径1011 //设置Html中 注意"~"对基于后台程序来动态解析的 所以Img标签 添加Runat=“Server” 在服务器端可以访问到12 this.clintimg.Src=getclintpath;//测试结果成功显示13 }

来看一下对于服务器端控件页面控制显示方式:

1 //getfilepath是从数据库获得图片存储绝对路径[markLinkUrl]的值2 if(!string.IsNullOrEmpty(getfilepath))3{4 //截取文件的名称5 stringgetclintpath=getfilepath.Substring(getfilepath.LastIndexOf('\\'));67 //服务器端-重置获取当前路径下服务器端虚拟应用程序根路径-成功8 //使用"/"所有的路径都是从站点的跟目录开始的,例如/default.aspx指向的是localhost/default.aspx9 this.Image2.ImageUrl=HttpContext.Current.Request.ApplicationPath+@"FileuploadDict"+getfilepath.Substring(getfilepath.LastIndexOf('\\'));10 //测试结果:页面成功显示11 }

在设置服务器端Image控件时用的是HttpContent.current.Request[获取当前请求的HttpRequest对象].ApplicationPath[获取服务器上 ASP.NET 应用程序的虚拟应用程序根路径]来设置.我们来比对一下页面的路径:

Html中标签: ~\FileuploadDict\2010-02-03-08-35-47rr4hnz45msimfqzh4tcdv545http_imgload6.jpg

Image服务端控件: /FileuploadDict\2010-02-03-08-35-47rr4hnz45msimfqzh4tcdv545http_imgload6.jpg

上面用的都是虚拟目录下相对路径来访问,如果直接通过拼接类似如上字符串 来对控件赋值 在Html页面时不识别的 ~/ 仅对 ASP.NET  的服务器空件起作用,.其实这就是关于Asp.net中相对路径的使用问题:处理方式如下;

(A): 如果链接中,源端点和目标端点在同一个目录下,则在链接中只需要指明目标端点的文档名称就可以了

(B):使用"/"所有的路径都是从站点的跟目录开始的,例如/default.aspx指向的是localhost/default.aspx

(C):如果在链接中,源端点和目标端点不位于同一个目录下,则只需要将目录的相对关系表达出来就可以了。如果链接指向的文档没有位于当前目录的子级目录中,则可以利用”..”符号来表示当前的父目录,多个..符号可以表示根高的父级目录,从而构建出目录的相对位置.

(D):在ASP.NET里增加了一个新的表达方法“~”,“~”表示的路径是当前应用程序的跟目录。“~”和上面介绍的“/”最大的区别是由服务器进行动态解释。由于”~”是相对于应用程序的根目录,所以利用它可以简化路径的设置,在某些情况下似乎还必须使用该控件

前面3种方法都是客户端解析的,也就是html种的源码就是这样,由浏览器来解析定向;而第四种方法是在服务器端解析,浏览器并不识别,所以常常在后台拼接时会出现字符串和服务器控件字符串相同 页面却无法显示图片问题,归咎还是Asp.net相对路径使用问题.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值