C#实现图片从数据库的上传和下载

Sql Sever 的图片储存

sql sever的图片是以字节的形式存储的,在我的认知范围内,想要在数据库存储图片是需要建立存储过程的,然后声明一个图片变量用于存储图片,sql sever为图片的储存建立了专用的数据类型即Image类型。
另一种方法是设置一个字符串的字段,里边存放图片的路径,当然这就需要在程序中提供图片,用户在安装软件时,图片也要作为程序的一部分

在C#中图片存储

如果是第二种方法就比较简单,只需要提前配置好图片即可,并在需要时读取路径来从本地加载。
我是采用的直接上传图片的方法,其实并不理想,当我仅仅放了五张图片时,读取就比较慢了,也可能是我为打他GirdView控件直接添加了数据源,而数据源中也会把图片读取下来,后期我会改一下,试试是不是因为控件的原因。

在此参考了大神的博客:
https://www.cnblogs.com/hfzsjz/archive/2010/05/21/1740778.html

并在此基础上添加了自己需要的东西,因为该博客是单独举例说明了图片的上传和读取,而我们在写程序时往往不会将只设置一个图片的字段,没想到当我写完是运行出来却很好,因为我并不太会sql语法,只是会基础的更新语句。
按照我的理解(如果错了希望可以指点纠正)
在用C#实现时需要为它提供参数
SqlParameter parameter = new SqlParameter(“Img”, SqlDbType.Image);
这句话就是声明一个参数名字是Img,图像类型


            if(dialog.ShowDialog() == DialogResult.OK)
            {
                string fileName = dialog.FileName;

                using (FileStream fs = new FileStream(fileName, FileMode.Open))
                {
                //在此处读取图片,并转化为字节,然后赋值给imagebytes(byte[])字节数组
                    imagebytes = new byte[fs.Length];
                    BinaryReader br = new BinaryReader(fs);
                    imagebytes = br.ReadBytes(Convert.ToInt32(fs.Length));
                    panImg.BackgroundImage = Image.FromStream(fs);
                    fs.Close();
                } 
            }
           
            if (txtMsg.Text != "" && txtName.Text != "" && txtNum.Text != "" && txtPrice.Text != "" && txtType.Text != "")
            {
                con.Open();
                if(imagebytes == null) //判断字节数组是否为空,空则代表用户没有上传图片
                {
                    cmd.CommandText = string.Format("update tb_food set foodty = {0},foodname = '{1}'," +
                    "foodprice = '{2}',foodmsg = '{3}' where foodnum = '{4}'", txtType.Text.Trim(), txtName.Text.Trim(),
                    txtPrice.Text.Trim(), txtMsg.Text.Trim(), txtNum.Text.Trim());

                    cmd.ExecuteNonQuery();
                }
                else
                {
                    cmd.CommandText = string.Format("update tb_food set foodImg = @Img ,foodty = '{0}',foodname='{1}'," +
                    "foodprice = '{2}',foodmsg = '{3}' where foodnum = '{4}'", txtType.Text.Trim(), txtName.Text.Trim(),
                    txtPrice.Text.Trim(), txtMsg.Text.Trim(), txtNum.Text.Trim());

                    cmd.Parameters.Add(parameter); //在此处为存储过程添加参数
                    cmd.Parameters["Img"].Value = imagebytes; //设置参数为图片的字节数组

                    cmd.ExecuteNonQuery();
                    cmd.Parameters.Remove(parameter); //移除参数,
                    //可能是添加参数后会在数据库被声明,如果不移除的话,我们再次添加图片时会报错
                    //错误信息是该参数已被声明,具体不记得了大概是这意思。
                    //为解决这个问题我想过在该模块外声明一次就不会被重复声明,但是带来的问题却是会影响其他的不需要参数的命令,因为他们是公用一个cmd的,应该也可以单独建立一个cmd,具体我也没有试过。
                }

                con.Close();
            }

读取

                byte[] imagebytes = (byte[])sdr.GetValue(sdr.GetOrdinal("foodImg"));
                if (imagebytes.Length != 0)
                {
                    MemoryStream ms = new MemoryStream(imagebytes);
                    Bitmap bmpt = new Bitmap(ms);
                    panImg.BackgroundImage = bmpt;
                }
                else
                {
                    panImg.BackgroundImage = null;
                }

读取就很简单了直接将字节转化为图片并赋值给一个接收的对象即可。

一些感想

因为疫情,已经很久没有出门了,说实话在学校的学习气氛确实比家里的好得多,我人为环境还是很有必要的,我在学校的社团工作室可以一坐一下午,但是现在真的没有耐心,希望可以早日开学,祖国加油!!!

你可能感兴趣的:(C#实现图片从数据库的上传和下载)