困扰了我一天半的图片转化存取今天终于解决了,图片的存取只是比普通数据的存取多了个转换数据的过程,这个转换是真的皮啊。
话不多说,先看整体效果:
转化图片为二进制流+存入数据库+将二进制流图片转化为图片并显示在图片框
/// <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();
}
}