系列文章
- 基於.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}張圖片"
};
}
匯入完成後介面返回圖片列表
實現效果
皮一下… 這部分沒有圖片,等下一篇介紹圖片瀑布流就有啦~