前台控件为image控件,需要指定控件的imagesoure属性,因此需要将WriteableBitmap对象转换为BitmapImage对象
public BitmapImageAndByte ConvertWriteableBitmapoBitmapImage(WriteableBitmap writeableBitmap) { BitmapImage bitmapImage = new BitmapImage(); using (MemoryStream stream = new MemoryStream()) { PngBitmapEncoder encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(writeableBitmap)); encoder.Save(stream); bitmapImage.BeginInit(); bitmapImage.CacheOption = BitmapCacheOption.OnLoad; bitmapImage.StreamSource = stream; bitmapImage.EndInit(); bitmapImage.Freeze(); } return bitmapImage; }
指定image控件的imageSource属性为该bitmapImage,即可显示图片
相关链接:
WPF图片处理
WriteableBitmap和BitmapImage的相互转换
图片保存到MySQL数据库需要先将不同格式的图片保存为byte[ ]数组,无论是本地图片还是网络图片,或者是本次需求中内存里的图片,道理是一样的:转换为byte,存入数据库。
数据库中的字段类型可以根据自己要存取图片的大小来决定,tinyblob、blob、mediumblob等等。
数据库类型如下:
根据需求,我需要将WriteableBitmap对象转化为byte数组
public byte[] ConvertWriteableBitmapToByte(WriteableBitmap writeableBitmap) { byte[] imgByte = null; using (MemoryStream stream = new MemoryStream()) { try { stream.Position = 0; using (BinaryReader br = new BinaryReader(stream)) { imgByte = br.ReadBytes((int)stream.Length); } } catch (Exception ex) { Console.WriteLine("convert error:" + ex.ToString()); } } return imgByte; }
这段代码和第一步中的转换类似,可以根据需要合并在一个函数中。
public byte[] PostureByte1 { get; set; } public void SaveImgToDatabase() { String connetStr = "server=localhost;port=3306;user=root;password=1234;database=test;"; MySqlConnection conn = null; try { conn = new MySqlConnection(connetStr); //string sql = "insert into testimages(img) values('{0}')"; //sql = string.Format(sql, PostureByte1); //MySqlCommand cmd = new MySqlCommand(sql, conn); MySqlCommand cmd = new MySqlCommand(); cmd.CommandText= "insert into testimages(img) values(@img)"; cmd.Parameters.Add("@img", MySqlDbType.MediumBlob);//数据类型很重要 cmd.Parameters[0].Value = PostureByte1;//0代表commandText中的第一个参数 cmd.Connection = conn;//设置数据库连接 conn.Open(); var result = cmd.ExecuteNonQuery(); if (result != -1) { Console.WriteLine("插入成功,插入的byte[]长度为:" + PostureByte1.Length); } } catch (Exception ex) { Console.WriteLine("插入失败:" + ex.ToString()); } finally { if (conn!=null) { conn.Close(); } } }
注意上段代码中注释掉的部分,直接存放byte到数据库中,会丢失数据。这就造成取出取出byte后,无法还原为图片。所以需要在放入数据库时指定数据的类型为MySqlDbType.MediumBlob。
存放结果:
相关链接:
C#读取Mysql blob字段
C#数据库操作
分为两部分,首先从数据库中取出blob数据,也就是byte[],然后将其转换为BitmapImage对象
public byte[] ShowImgFromDatabase() { String connetStr = "server=localhost;port=3306;user=root;password=1234;database=test;"; MySqlConnection conn = null; byte[] imgbyte=null; try { conn = new MySqlConnection(connetStr); conn.Open(); string sql = "select * from testimages"; MySqlCommand cmd = new MySqlCommand(sql, conn); MySqlDataReader reader = cmd.ExecuteReader(); if (reader.Read())//这里只取出了数据库中的一个记录,根据需要自行更改逻辑 { long len = reader.GetBytes(reader.GetOrdinal("img"), 0, null, 0, 0);//先获取字段的长度 imgbyte = new byte[len];//根据获取到的长度初始化一个byte数组 len = reader.GetBytes(reader.GetOrdinal("img"), 0, imgbyte, 0, (int)len);//将数据写入数组 } reader.Close(); return imgbyte; } catch (Exception ex) { Console.WriteLine("读取失败:" + ex.ToString()); return null; } finally { if (conn != null) { conn.Close(); } } }
private BitmapImage ConvertByteToBitmapImage(byte[] imgbyte) { BitmapImage bmp = null; try { using (var ms = new MemoryStream(imgbyte)) { ms.Seek(0, SeekOrigin.Begin); bmp = new BitmapImage(); bmp.BeginInit(); bmp.CacheOption = BitmapCacheOption.OnLoad; bmp.StreamSource = ms; bmp.EndInit(); bmp.Freeze(); } return bmp; } catch (Exception ex) { Console.WriteLine("转换失败:"+ex.ToString()); bmp = null; } return bmp; }
获取到BitmapImage后,赋值给对应的image控件,完成显示。
相关链接:
BitmapImage和byte[]相互转换