一個網站,圖片數據是一定存在的;圖片存儲如何處理,有很多方式。
自己總結兩種:1、將圖片保存為靜態文件形式;(優點:文件容易轉移、備份;缺點:文件丟失不易恢復)2、將圖片轉換為字節流獲其他方式獲取圖片完整數據進行存儲(優點:數據庫保存,不易丟失;缺點:數據庫空間增長較快)
之前圖片保存是通過保存文件名稱等基本信息,未對圖片的原始內容進行處理;最近 想換種方式進行圖片數據保存;特記錄。
保存文件完整信息,常用的方式是將文件轉換為二進制流,保存進數據庫,當然也可以保存圖片為base64 數據流。
1、工具: 數據庫SQLServer 2012 R2;開發語言:C# ;展示形式:通過MVC 進行web 處理展示。
2、數據庫圖片信息表 核心字段介紹:FileContent varbinary(max) NULL, ----圖片內容保存字段,字段類型 varbinary(max) -->對應C# 中字段類型 byte[]
3、獲取圖片文件字節流(用於數據庫存儲)
/// <summary> /// 根據圖片路徑返回圖片的字節流byte[] /// </summary> /// <param name="imagePath">圖片路徑</param> /// <returns>返回的字節流</returns> public static byte[] getImageByte(string imagePath) { FileStream files = new FileStream(imagePath, FileMode.Open); byte[] imgByte = new byte[files.Length]; files.Read(imgByte, 0, imgByte.Length); files.Close(); return imgByte; }
4、將獲取到的圖片字節流存入數據庫
/// <summary> /// 添加圖片內容信息到數據庫 /// </summary> /// <param name="path"></param> /// <returns></returns> public static int InsertImg(string path) { //----------以文件的方式讀取圖片並轉化成字節流 FileStream fs = new FileStream(path, FileMode.Open); byte[] imgSourse = new byte[fs.Length]; fs.Read(imgSourse, 0, imgSourse.Length); fs.Close(); //--------------讀取圖片並轉化成字節流結束---------------- using (SqlConnection conn = new SqlConnection(SqlHelper.connStr)) { conn.Open(); using (SqlCommand cmd = conn.CreateCommand()) { //cmd.CommandText = "update PictureInfo set FileContent=@ImageLogo "; cmd.CommandText = "insert into PictureInfo (FileContent) VALUES FileContent=@fileContent"; //cmd.Parameters.Add("@fileContent", System.Data.SqlDbType.Image); cmd.Parameters.Add(new SqlParameter("@fileContent", imgSourse)); return cmd.ExecuteNonQuery(); } } }
5、讀取數據庫中圖片信息展示到頁面(Winform 中有Picture 控件,可以直接使用Image 展示;MVC 中需要做一些處理。)
(1)、Winform 中展示
/// <summary> /// 展示單張圖片到頁面 /// </summary> public void ReturnImageShow() { //.....省略數據獲取過程 //獲取存儲的某圖片字節流 byte[] ImageLogoArray = row["FileContent"] is DBNull ? null : (byte[])(row["FileContent"]); MemoryStream ms = null; if (ImageLogoArray != null) { ms = new MemoryStream(ImageLogoArray); this.picBox.Image = new Bitmap(ms); } }
(2)、MVC 中展示(后台)
// GET: Pictures/Index /// <summary> /// 數據展示方法(使用前台js 處理、調用渲染img 的src ) /// </summary> /// <returns></returns> public ActionResult Index() { using (DataContext dbContext = new DataContext()) { //獲取待展示列表數據 PictureInfoService infoService = new PictureInfoService(dbContext); var userList = dbContext.Set<PictureInfo>(); //傳值list<T> 數據 ViewData["PicInfo"] = userList.ToList(); } return View(); } // GET: Pictures/IndexAdv /// <summary> /// 展示數據(后台直接拼接圖片標簽內容,使用頁面傳值方法直接在頁面渲染) /// </summary> /// <returns></returns> public ActionResult IndexAdv() { using (DataContext dbContext = new DataContext()) { //獲取所需數據 PictureInfoService infoService = new PictureInfoService(dbContext); var userList = dbContext.Set<PictureInfo>(); //后台格式化文本直接讀取 StringBuilder builder = new StringBuilder(); foreach (var data in userList) { //此處 src 屬性賦值 需要指向后台字節流轉換方法 builder.AppendFormat(" <div class=\"item\"><img id=\"image{0}\" src=\"../Pictures/ReturnPic?id={1}&random=Math.random()\" title=\"{2}\" /></div>", data.Id, data.Id, data.FileName); } //后台拼接的頁面標簽 //MVC (非Core )前台識別HTML 使用 @Html.Raw(ViewBag.DataBuilder) ViewBag.DataBuilder = builder.ToString(); } return View(); } /// <summary> /// 返回圖片(后台添加圖片字節流處理方法) /// </summary> /// <param name="id">查詢條件(id索引)</param> /// <returns></returns> public FileStreamResult ReturnPic(int id) { using (DataContext dbContext = new DataContext()) { //本處使用的EF ,只做示例;主要獲取對應的圖片內容信息byte[] PictureInfoService infoService = new PictureInfoService(dbContext); var data = infoService.Find<PictureInfo>(id); //將獲取到的字節流放入MemoryStream ,用於返回 //MVC 中前台展示字節流的圖片,需要特殊處理, //返回類型為 FileStreamResult MemoryStream ms = new MemoryStream(data.FileContent); return new FileStreamResult(ms, "image/jpeg"); } }
(3)、MVC 展示前台部分
IndexAdv.cshtml
Index.cshtml
6、圖片字節流一般轉換封裝
using System.Drawing; using System.IO; public class ImgTransHelper { /// <summary> /// 圖片轉換成字節流 /// </summary> /// <param name="img">要轉換的Image對象</param> /// <returns>轉換后返回的字節流</returns> public static byte[] ImgToByt(Image img) { MemoryStream ms = new MemoryStream(); byte[] imagedata = null; img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); imagedata = ms.GetBuffer(); return imagedata; } /// <summary> /// 字節流轉換成圖片 /// </summary> /// <param name="byt">要轉換的字節流</param> /// <returns>轉換得到的Image對象</returns> public static Image BytToImg(byte[] byt) { MemoryStream ms = new MemoryStream(byt); Image img = Image.FromStream(ms); return img; } /// <summary> /// 根據圖片路徑返回圖片的字節流byte[] /// </summary> /// <param name="imagePath">圖片路徑</param> /// <returns>返回的字節流</returns> private static byte[] getImageByte(string imagePath) { FileStream files = new FileStream(imagePath, FileMode.Open); byte[] imgByte = new byte[files.Length]; files.Read(imgByte, 0, imgByte.Length); files.Close(); return imgByte; } }
以上為記錄內容,如有不足之處,歡迎指正!