正文

把图片文件存到数据库时, 在通过WEB页查询时动态生成2005-05-10 13:55:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/Csharpsky/923.html

分享到:

需求是: 1.网站需要提供图片上传 2.图片不能用文件的方式保存, 只能保存到数据里. 3.查询页面里动态生成图像.     一般都是用保存图片文件的方式, 在服务器上找个地方存下来, 然后数据库保存这个文件的WEB链接. 但是如果不允许用保存文件的方式, 而要求必须将图片数据直接存在数据库里呢?     第一个问题是解决上传和保存的问题. 比如有一个网站提供DVD的资料, 用户可以自行加入新的DVD介绍文字和一个说明图片进去. 介绍和图片都放到数据库里, 文字资料不用说了, 主要是图片.     以SQLSERVER为例:     在SQLSERVER里建一个表来保存相关的信息,  如dvdimg, CREATE TABLE [dbo].[DvdImg] (      DVDID [int] NOT NULL ,      Img [image] NULL ,      filetype [char] (10)  NOT NULL ) ; DVDid是关联到DVD主信息表的DVD唯一识别符, 为了让数据库快一点, 我把数据和图像分开了. 在上传页面上放一个文件上传控件,  就是下面这个东西: protected System.Web.UI.HtmlControls.HtmlInputFile fEDImg; 名字就是: fEDImg 加一个保存按钮, 写个click事件的处理, 把数据insert到数据库里, 咱们主要说保存图片的这一段.              if (this.fEDImg.PostedFile.ContentLength != 0)               {                  // 加入图片                  int intDocLen = this.fEDImg.PostedFile.ContentLength;                  byte[] Docbuffer = new byte[intDocLen];                     Stream objStream;                     objStream = this.fEDImg.PostedFile.InputStream;                     objStream.Read(Docbuffer,0,intDocLen);                  objStream.Close();                  SqlConnection conn = Global.GetConn();                                     SqlCommand cmd = conn.CreateCommand();                  conn.Open();                  cmd.CommandText = "delete from dvdimg where dvdid = "+dvd.DVDID.ToString();                  cmd.ExecuteNonQuery();                        int iLastIndex =this.fEDImg.PostedFile.FileName.LastIndexOf(".");                  string sExtFileName = this.fEDImg.PostedFile.FileName.Substring(                      iLastIndex + 1,                      this.fEDImg.PostedFile.FileName.Length - iLastIndex -1                      );                                     cmd.CommandText ="insert into dvdimg (dvdid, img, filetype) values (@dvdid, @img, @filetype)";                  cmd.CommandType = CommandType.Text;                  cmd.Parameters.Add("@dvdid",SqlDbType.Int);                  cmd.Parameters.Add("@img",SqlDbType.Image);                  cmd.Parameters.Add("@filetype",SqlDbType.Char);                  cmd.Parameters[0].Value =dvd.DVDID;                  cmd.Parameters[1].Value = Docbuffer;                  cmd.Parameters[2].Value = sExtFileName;                     cmd.ExecuteNonQuery();                  conn.Close();                 } Global.GetConn()是得到数据库连接对象的方法, 我喜欢把这种全局性的东西放到这里. 不必多说. 这样一来, 图片就保存好了. 注意, 文件格式一定要保存, 不然以后就不知道这是什么东西了. 第二是浏览, 这里有一个问题, 就是图片数据是在数据库里,  而页面上显示图像时用的是<img>元素, 其中的src属性该如何写? 有人这么做: 把图片取出来之后, 生成一个临时文件, 然后把页面文件里的img的src指到这个文件里. 当然这样也可以解决问题, 但是有几个问题: 一是慢, 要写硬盘的, 二是临时文件什么时候删? 定期删吗? 网站访问量大了怎么办? 不好. 最好的解决办法是把img的src指向一个程序, 而不是一个文件, 由这个程序来生成图像, 向浏览器发送. 那么, 生成信息浏览页面时, 在显示画面的地方就可以这样写: <img src=http://XXX.XXX.XXX/queryimg.aspx?dvdid=123> 向queryimg.aspx传一个参数, 也就是需要的DVD图像的编号. 然后, 可以新建一个queryimg.aspx页面文件, 记得, 一定要把page的Visible设为false, 这样页面的文件就不会出现了, 怎么输出都是靠你的程序. 然后在page_load里写下面一段这样的代码.    private void Page_Load(object sender, System.EventArgs e) {      // 在此处放置用户代码以初始化页面      this.Visible = false;                  int id = Convert.ToInt32( this.Request["id"]);         sqlConnection1 = Global.GetConn();      byte [] arImg;      string sExtFileName;      // 下面这里我用了数据集的绑定。用datareader也可以,这一段无关紧要。      this.sqlDataAdapter1.SelectCommand.Parameters[0].Value = id;      this.sqlDataAdapter1.Fill(this.db1);             if (this.db1.DvdImg.Rows.Count == 0)      {          // 没有的话就转到一个事先准备的“没有图片”的地址上。          this.Response.Redirect("images/noimg.jpg");          return;      }      sExtFileName = this.db1.DvdImg[0].filetype;      arImg = this.db1.DvdImg[0].Img;             // 注意,下面要修改输出的mime格式,不然浏览器是不知道这是什么玩意儿的。      // 不全,也就是个大概齐,大家可以加补充。      string sMimeType;      switch (sExtFileName)      {          case "jpg":              sMimeType = "jpeg";              break;          case "bmp":              sMimeType = "bitmap";              break;          case "gif":              sMimeType = "gif";              break;          case "tif":              sMimeType = "tiff";              break;          default:              sMimeType = "jpeg";              break;      }      Response.ContentType="image/" + sMimeType;             // 写字节流到浏览器。      Response.BinaryWrite(arImg);         this.db1.Dispose(); }    Hmm, 好了. 现在已经可以动态地生成图像流了, 没有临时文件, 一切干干净净

阅读(43998) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册