zoukankan      html  css  js  c++  java
  • image控件与数据库中二进制图片的交互(存储与读取)

          首先引入这个问题,一个注册会员的网站,一般会要求用户上传头像。这里我们就是针对上传头像这一模块,做相应的操作。

          当用户把头像上传到注册页面后,注册页面要显示这个头像,还能在此会员下次登录这个网站时,显示出会员的头像,那么我们头像的信息应该也与会员别的信息一样被存入到数据库中,即数据库里有一个字段是关于头像的。至于这个字段到底应该存什么,可以分为两种情况:存入头像的链接地址,即imageURL;或头像转为二进制流后存入。本例中我们的数据库从简,只设置两个字段(会员编号cBh,会员头像bPhoto),头像是以二进制流存入数据库的。

         先来看看我们页面上关于头像上传的部分,如下图所示:

    与此部分对应的前台HTML页面代码为:

    HTML代码
     1    <td align="center" class="style1">
     2                <asp:Image ID="photo" runat="server" Width="125px" Height="120px" ImageAlign="Middle" 
     3                    BorderWidth="1px" ImageUrl="~/images/photo.jpg"   />
     4                                     
     5     </td>
     6     <td class="style5">
     7           <table id="tab">
     8                <tr>
     9                    <td class="style6" align="center">
    10                    <label>请选择要上传的照片<br />
    11                    &nbsp;支持格式.jpg与.bmp!</label></td>
    12                </tr>
    13                <tr>
    14                    <td class="style6">
    15                      <asp:FileUpload  runat="server" ID="choicePhoto" Width="217px"/>
    16                    </td>                    
    17                </tr>
    18                <tr>
    19                    <td class="style6" align="center">                  
    20                       &nbsp;&nbsp;&nbsp;&nbsp;                  
    21                       <asp:Button runat="server" Text="上传照片" Width="119px" ID="importPhoto" 
    22                            onclick="importPhoto_Click" />
    23                    </td>
    24                </tr>   
    25            </table>
    26     </td>

         用户对应的操作为:点击浏览,然后选择好要上传的图片后,点击上传照片。关于浏览按钮,下节将做详细介绍

        上传照片按钮的代码为:

    View Code
     1 protected void importPhoto_Click(object sender, EventArgs e)
     2  {
     3        this.funImportPhoto();
     4  }
     5 private void funImportPhoto()
     6  {
     7       string filePath = this.choicePhoto.PostedFile.FileName.ToString().Trim();//文件路径 
     8        string fileName = filePath.Substring(filePath.LastIndexOf("\\") + 1);//文件名
     9        string fileEx = fileName.Substring(fileName.LastIndexOf(".") + 1);//文件后缀名
    10        string relativeName = "~/images/";//相对
    11        string absoluteName = Server.MapPath(relativeName);//绝对,这里需要注意,relativeName是必须存在的,即有这个目录
    12        if (fileEx == "jpg" || fileEx == "bmp")
    13        {
    14             string newFileName = Guid.NewGuid().ToString();//生成新的文件名,保证唯一性
    15             string newFilePath = absoluteName  + newFileName + "." + fileEx;
    16             this.choicePhoto.PostedFile.SaveAs(newFilePath);//将文件存储到服务器上
    17             this.photo.ImageUrl = relativeName + newFileName + "." + fileEx;
    18         }
    19         else
    20         {
    21               ShowMessage("请选择正确的照片格式!", "");
    22         }
    23 
    24  }

         上述代码里面的 string filePath = this.choicePhoto.PostedFile.FileName.ToString().Trim();这一行需要做详细的解释。这一句是获得图片路径的方法(不同的浏览器有不同的值),目前我接触到的IE6和FireFox得到的结果就不一样。IE6获得的是图片的绝对路径,而FireFox只能得到图片的名字而已。所以为了通用性,我们暂且忽略这一行得到的到底是名字还是路径,我们都要通过上述的代码,先从此结果里截取出图片的名字(上面funImportPhoto()函数里的的第二行)。然后为图片设置一个虚拟路径先暂存图片,然后再将图片的暂存相对路径付给image控件的imageURL。

         至此当你点击上传图片运行完上述代码后,你会发现你的界面变成:

        这个显示类似于预览的功能,只是让你看到你上传的头像在界面中显示的样子,这里还没有将图片保存进数据库中。

        正常操作下,当会员填好自己的一切信息后,点击保存才会进行信息的提交。提交的数据才会被存入到数据库中,在数据库里bPhoto字段的类型为:

        保存按钮的函数为:

    protected void save_Click(object sender, EventArgs e)
    {
         People pe = new  People() ;
         pe.cBh = this.txtBh.Text;
         pe.bPhoto = this.storePhoto();//从控件读取图片信息的函数
    }

    上述的storePhoto()为从image控件读取到图片信息,并将其转成二进制流后,赋给会员People类的对象pe的bPhoto属性:

     1 private Byte[] storePhoto()
     2  {            
     3         string pictureURL = this.photo.ImageUrl;
     4         string picturePath = Server.MapPath(pictureURL);//绝对路径
     5         FileStream fs = new FileStream(picturePath, FileMode.Open, FileAccess.Read);
     6         BinaryReader br = new BinaryReader(fs);
     7         byte[] bytes = br.ReadBytes((int)fs.Length);
     8         br.Close();
     9         fs.Close();
    10         return bytes;
    11 }

    然后就是将对象pe的各属性存入到数据库中:

    存入数据库中的代码
     1 StringBuilder strSql = new StringBuilder();
     2 strSql.Append("insert into people(");            
     3 strSql.Append("cBh,bPhoto )");
     4 strSql.Append(" values (");                       strSql.Append("@cBh,@bPhoto)");
     5 SqlParameter[] parameters =
     6 {
     7         new SqlParameter("@cBh", SqlDbType.NVarChar,20),
     8         new
     9 SqlParameter("@bPhoto",SqlDbType.VarBinary,1000000)//2013-04-24
    10 };
    11 parameters[0].Value = pe.cBh;
    12 parameters[1].Value = pe.BPhoto;
    13 object obj = DbHelperSQL.GetSingle(strSql.ToString(), parameters);
    GetSingle
     1 public static object GetSingle(string SQLString, params SqlParameter[] cmdParms)
     2 {
     3        using (SqlConnection connection = new SqlConnection(connectionString))
     4        {
     5              using (SqlCommand cmd = new SqlCommand())
     6              {
     7                   try
     8                   {
     9                         PrepareCommand(cmd, connection, null, SQLString, cmdParms);
    10                         object obj = cmd.ExecuteScalar();
    11                         cmd.Parameters.Clear();
    12                         if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))
    13                         {
    14                             return null;
    15                         }
    16                         else
    17                         {
    18                             return obj;
    19                         }
    20                     }
    21                     catch (System.Data.SqlClient.SqlException e)
    22                     {
    23                         throw e;
    24                     }
    25                     finally
    26                     {
    27                         cmd.Dispose();
    28                         connection.Close();
    29                     }
    30              }
    31        }
    

    以上便是从image控件中读取到图片然后将信息转化为二进制流后存入数据库的操作。

    接下来我们思考从数据库中读取到图片后,将图片显示到image控件里,可以认为是上述操作的一个逆操作。

    先是用select语句从数据库中取得数据:

    从数据库中取出数据的代码
     1 StringBuilder strSql = new StringBuilder();
     2 strSql.Append("select cBh ,bPhoto from people ");
     3 strSql.Append(" where cBh=@cBh ");
     4 SqlParameter[] parameters = 
     5 {
     6       new SqlParameter("@cBh", SqlDbType.NVarChar,20),
     7 };
     8 parameters[0].Value =pe.cBh ;
     9 People pe = new People();
    10 DataSet ds = DbHelperSQL.Query(strSql.ToString(), parameters);//这个函数要自己编写,即将查询数据存入到dataset中
    11 if (ds.Tables[0].Rows.Count > 0)
    12 {
    13       pe.cBh = ds.Tables[0].Rows[0]["cBh"].ToString();
    14       if (ds.Tables[0].Rows[0]["bPhoto"].ToString() != "")
    15       {
    16            pe.BPhoto = (byte[])ds.Tables[0].Rows[0]["bPhoto"];////
    17       }
    18       else
    19            pe.BPhoto=new byte[0];
    20       return pe;
    21 }
    22 else
    23 {
    24       return null;
    25 }

    至此,数据已经读出来了,接下来就是显示了,你会发现这完全就是从image读取这个步骤的一个逆操作,部分代码如下:

    显示在image控件上
     1 if (pe.BPhoto.Length<1)//如果此人没有上传头像则头像为系统默认头像
     2 {
     3       this.photo.ImageUrl = "~/images/photo.jpg";
     4 }
     5 else 
     6 {
     7        byte[] picture = uworker.BPhoto;
     8        string strRotePath = "~/images";
     9        string strName = Guid.NewGuid().ToString();
    10        string strPath = strRotePath + "/" + strName + ".jpg";
    11        string strAbsolutePath = Server.MapPath(strPath);
    12        FileStream fs = new FileStream(strAbsolutePath, FileMode.OpenOrCreate, FileAccess.Write);
    13        BinaryWriter bw = new BinaryWriter(fs);
    14        bw.Write(picture);
    15        bw.Flush();
    16        bw.Close();
    17        fs.Close();
    18        this.photo.ImageUrl = strPath;              
    19 }

    当然其实更好的方法是将图片的URL地址存入数据库,以上的操作中只需要将自动产生的路径赋给相应控件就行了,这里就不做详细介绍。

    好了,以上就是全部的操作了。希望能帮到在读的你。

  • 相关阅读:
    定时器的实现
    派遣函数
    IRP的同步
    duilib基本流程
    驱动程序的同步处理
    WFP在包含fwpmu.h头的时候出错
    自己写的驱动用CreateFile打开时错误码返回1的问题
    Windows内核函数
    16_会话技术_Session
    15_会话技术_Cookie
  • 原文地址:https://www.cnblogs.com/huang1990/p/3043631.html
Copyright © 2011-2022 走看看