系列文章
基于.NetCore開發博客項目 StarBlog - (1) 為什么需要自己寫一個博客?
基于.NetCore開發博客項目 StarBlog - (2) 環境準備和創建項目
基于.NetCore開發博客項目 StarBlog - (3) 模型設計
基于.NetCore開發博客項目 StarBlog - (4) markdown博客批量導入
基于.NetCore開發博客項目 StarBlog - (5) 開始搭建Web項目
基于.NetCore開發博客項目 StarBlog - (6) 頁面開發之博客文章列表
基于.NetCore開發博客項目 StarBlog - (7) 頁面開發之文章詳情頁面
基于.NetCore開發博客項目 StarBlog - (8) 分類層級結構展示
基于.NetCore開發博客項目 StarBlog - (9) 圖片批量導入
...
前言
前面把分類層級結構做出來了,不過還不完美,然后我就又折騰了一波,把那個組件fork了一份魔改實現了我要的效果,還順便上傳了NPM包,詳情可以看這篇文章:魔改了一下bootstrap-treeview組件,發布個NPM包體驗一下
文章這部分就暫時完成了,接下來是攝影模塊,首先要搞定圖片的批量導入。
理清需求
先來看看模型設計
public?class?Photo?{[Column(IsIdentity?=?false,?IsPrimary?=?true)]public?string?Id?{?get;?set;?}public?string?Title?{?get;?set;?}public?string?Location?{?get;?set;?}public?string?FilePath?{?get;?set;?}public?long?Height?{?get;?set;?}public?long?Width?{?get;?set;?}public?DateTime?CreateTime?{?get;?set;?}
}
PS:其中Location
是照片的拍攝地點,FilePath
是存儲相對路徑。
之前路線圖中設定的是要支持圖片Exif數據讀取并自動定位,不過目前第一版沒有實現,需要手動輸入地點,存在Location
字段中。
然后還有需要讀取圖片的長跟寬,保存起來,后面做瀑布流展示的時候有用。
那么,流程也理清了:掃描目錄 -> 復制圖片 -> 讀取圖片信息 -> 保存到數據庫
代碼實現
OK,可以開始寫代碼了
掃描目錄和復制都比較簡單,先來看看如何獲取圖片的尺寸。
在.Net Framework時代,框架內置有操作圖片的標準庫,但.Net Core時代就無了,好像是因為之前的庫是跟GDI這種Windows平臺獨有技術綁定的,為了跨平臺只能砍了
不過.NetCore有個非常厲害的ImageSharp
庫可以操作圖片,作者是SixLabors,這名字很有意思啊,六個勞工,哈哈
讀取圖片
那么先來寫個讀取圖片信息的方法
編輯StarBlog.Web/Services/PhotoService.cs
文件,在PhotoService
中添加方法
using?SixLabors.ImageSharp;public?class?PhotoService?{///?<summary>///?獲取圖片的物理存儲路徑///?</summary>///?<param?name="photo"></param>///?<returns></returns>private?string?GetPhotoFilePath(Photo?photo)?{return?Path.Combine(_environment.WebRootPath,?"media",?photo.FilePath);}///?<summary>///?重建圖片數據(掃描圖片的大小等數據)///?</summary>///?<param?name="photo"></param>///?<returns></returns>private?Photo?BuildPhotoData(Photo?photo)?{var?savePath?=?GetPhotoFilePath(photo);using?(var?img?=?Image.Load(savePath))?{photo.Height?=?img.Height;photo.Width?=?img.Width;}return?photo;}
}
傳入Photo對象,根據圖片完整路徑去加載,然后把寬度和高度存到對應的屬性里
批量導入
接著來寫批量導入的方法,完整代碼見:https://github.com/Deali-Axy/StarBlog/blob/master/StarBlog.Web/Services/PhotoService.cs
public?List<Photo>?BatchImport()?{var?result?=?new?List<Photo>();var?importPath?=?Path.Combine(_environment.WebRootPath,?"assets",?"photography");var?root?=?new?DirectoryInfo(importPath);foreach?(var?file?in?root.GetFiles())?{var?photoId?=?GuidUtils.GuidTo16String();var?filename?=?Path.GetFileNameWithoutExtension(file.Name);var?photo?=?new?Photo?{Id?=?photoId,Title?=?filename,CreateTime?=?DateTime.Now,Location?=?filename,FilePath?=?Path.Combine("photography",?$"{photoId}.jpg")};var?savePath?=?GetPhotoFilePath(photo);file.CopyTo(savePath,?true);photo?=?BuildPhotoData(photo);_photoRepo.Insert(photo);result.Add(photo);}return?result;
}
只掃描一層文件目錄,不像博客批量導入那樣遞歸遍歷所有子目錄
因為圖片的沒有層級結構
這個方法最后返回導入的圖片列表
導入的圖片會復制到StarBlog.Web/wwwroot/assets/photography
下
沒有像導入博客那樣寫在單獨一個Project里是因為這個功能需要用接口來調用(其實導入博客也需要,后續我會整合到blogService中)
Controller
為了有始有終,把接口這部分代碼也貼一下
///?<summary>
///?批量導入圖片
///?</summary>
///?<returns></returns>
[Authorize]
[HttpPost("[action]")]
public?ApiResponse<List<Photo>>?BatchImport()?{var?result?=?_photoService.BatchImport();return?new?ApiResponse<List<Photo>>?{Data?=?result,Message?=?$"成功導入{result.Count}張圖片"};
}
導入完成后接口返回圖片列表
實現效果
皮一下… 這部分沒有圖片,等下一篇介紹圖片瀑布流就有啦~