C#玩转图片存取

困扰了我一天半的图片转化存取今天终于解决了,图片的存取只是比普通数据的存取多了个转换数据的过程,这个转换是真的皮啊。

话不多说,先看整体效果:

转化图片为二进制流+存入数据库+将二进制流图片转化为图片并显示在图片框

/// <summary>
        /// 将图片路径转为二进制流
        /// 数据库开销相对较小
        /// 通过商品名改图片
        /// 需要实例化实体和外观GoodsInfo,GoodsFacade
        /// </summary>
        /// <param name="pic"></param>
        public void Tupian(ref PictureBox pic,string goodsname)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "*jpg|*.JPG|*.GIF|*.GIF|*.BMP|*.BMP|*.png|*.PNG";

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                //选图片
                string filePath = ofd.FileName;//图片路径
                FileStream fs = new FileStream(filePath, FileMode.Open);
                //将图片转化为二进制
                byte[] imageBytes = new byte[fs.Length];
                BinaryReader br = new BinaryReader(fs);
                imageBytes = br.ReadBytes(Convert.ToInt32(fs.Length));
                //数据库更改图片
                string field = "picture";
                byte[] value = imageBytes;
                goods.goodsname = goodsname;
                bool result = goodsfacade.UpdateGoods(goods, field, value);
                //将二进制数据类型的图片显示在图片框
                MemoryStream ms = new MemoryStream(imageBytes);
                Bitmap bmp = new Bitmap(ms);
                pic.Image = bmp;
            }
        }

分析:这个方法职责较多,功能较单一,需要分开封装(遇到点问题,见下文)。

方法:
图片显示:

//二进制流转为图片并显示在图片框
        public void ShowImage(PictureBox pic, byte[] imageBytes)
        {
            MemoryStream ms = new MemoryStream(imageBytes);
            Bitmap bmp = new Bitmap(ms);
            pic.Image = bmp;
        }

分析:

里面的imageBytes是从数据库中取出的数据。再此特别强调,在查询数据库时,将图片的数据存到list里会报错:参数无效,原因可能是转存的时候将二进制流截下去了一部分,数据不完整。解决方法是将数据存在datatable里。具体原因,还望大佬来解答。

方法:

将图片转化为二进制流:

 public void ChangePicture()
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "*jpg|*.JPG|*.GIF|*.GIF|*.BMP|*.BMP|*.png|*.PNG";

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                //选图片
                string filePath = ofd.FileName;//图片路径
                FileStream fs = new FileStream(filePath, FileMode.Open);
                //将图片转化为二进制
                byte[] imageBytes = new byte[fs.Length];
                BinaryReader br = new BinaryReader(fs);
                imageBytes = br.ReadBytes(Convert.ToInt32(fs.Length));
            }
        }

分析:

这个方法封装了一个过程,而不是通过这个过程得到最后要用的数据(return…的写法会报错:并非所有的代码路径都有返回值)

刚开始的封装问题也正是出在了这里:方法里的imageBytes的值要被其他方法使用,但这个方法里要先打开图片文件,然后再选图片,选完图片后imageBytes才会有值,选的过程是在程序运行时手动执行的,所以,运行之前imageBytes是没有值的。怎样回避这个问题,我的想法是将选图片和转换数据分成两个方法,通过传参实现。

方法:

上边的存图片存的是图片路径,如果图片路径改了会带来麻烦,但可以减少数据库开销,下面是直接存图片数据的方法,缺点是数据库开销较大:

/// <summary>
        /// 将图片本身转为二进制流
        /// 数据较大,数据库开销很大
        /// </summary>
        public void Cun()
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "*jpg|*.JPG|*.GIF|*.GIF|*.BMP|*.BMP";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                string filePath = ofd.FileName;//图片路径
                FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
                BinaryReader br = new BinaryReader(fs);
                byte[] imageBytes = br.ReadBytes((int)fs.Length);
                br.Close();
                fs.Close();
            }
        }
发布了233 篇原创文章 · 获赞 22 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_41026669/article/details/98851330
今日推荐