linxihuanghuang

导航

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地址存入数据库,以上的操作中只需要将自动产生的路径赋给相应控件就行了,这里就不做详细介绍。

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

 

 

posted on 2013-04-25 22:03  linxihuanghuang  阅读(702)  评论(0编辑  收藏  举报