天天看點

基于.NetCore開發部落格項目 StarBlog - (9) 圖檔批量導入

系列文章

  • 基于.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) 圖檔批量導入
  • 基于.NetCore開發部落格項目 StarBlog - (10) 圖檔瀑布流
  • 基于.NetCore開發部落格項目 StarBlog - (11) 實作通路統計
  • 基于.NetCore開發部落格項目 StarBlog - (12) Razor頁面動态編譯
  • 基于.NetCore開發部落格項目 StarBlog - (13) 加入友情連結功能
  • 基于.NetCore開發部落格項目 StarBlog - (14) 實作主題切換功能
  • 基于.NetCore開發部落格項目 StarBlog - (15) 生成随機尺寸圖檔
  • 基于.NetCore開發部落格項目 StarBlog - (16) 一些新功能 (監控/統計/配置/初始化)
  • ...

前言

前面把分類層級結構做出來了,不過還不完美,然後我就又折騰了一波,把那個元件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}張圖檔"
    };
}
           

導入完成後接口傳回圖檔清單

實作效果

皮一下… 這部分沒有圖檔,等下一篇介紹圖檔瀑布流就有啦~

微信公衆号:「程式設計實驗室」

專注于網際網路熱門新技術探索與團隊靈活開發實踐,包括架構設計、機器學習與資料分析算法、移動端開發、Linux、Web前後端開發等,歡迎一起探讨技術,分享學習實踐經驗。

繼續閱讀