返回文章列表文章索引阅读全文
STARBLOG / 阅读手记
StarBlog博客开发笔记

StarBlog Blog Development Notes (9): Batch Importing Images

Series of articles Developing a Blog Project with .NetCore: StarBlog - (1) Why Do You Need to Write Your Own Blog? Developing a Blog Project with .NetCore: StarBlog - (2) Environment Setup and Creating the Project Developing a Blog Project with .NetCore: StarBlog - (3) Model Design Developing a Blog Project with .NetCore: StarBlog - (4) Batch Importing Markdown Blogs Developing a Blog Project with .NetCore: StarBl

曦远 (DealiAxy)约 17 分钟
目录8 个章节

Series of Articles

Preface

I previously got the category hierarchy working, but it still wasn't perfect, so I tinkered with it some more, forked that component and hacked it to get the effect I wanted, and while I was at it I published an NPM package. For details, see this article: I hacked the bootstrap-treeview component a bit and published an NPM package to try it out

The articles part is done for now. Next up is the photography module, and first I need to get batch image import working.

Clarifying the Requirements

Let's first look at the model design

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 is the place where the photo was taken, and FilePath is the relative storage path.

The original roadmap called for supporting reading image Exif data and auto-locating, but that isn't implemented in this first version—you have to enter the location manually, stored in the Location field.

We also need to read the image's height and width and save them, which will be useful later for the waterfall layout.

So the flow is clear as well: scan the directory -> copy images -> read image info -> save to the database

Code Implementation

OK, time to start writing code

Scanning the directory and copying are fairly straightforward. Let's first look at how to get the image dimensions.

In the .Net Framework era, the framework had a built-in standard library for working with images, but that's gone in the .Net Core era. Apparently the old library was tied to GDI, a Windows-only technology, so it had to be cut for cross-platform support.

But .NetCore has a really powerful ImageSharp library for working with images. The author is SixLabors—that's a fun name, six laborers, haha

Reading Images

So let's first write a method to read image info

Edit the StarBlog.Web/Services/PhotoService.cs file and add methods to 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;
    }
}

Pass in a Photo object, load it from the image's full path, then store the width and height in the corresponding properties

Batch Import

Next, let's write the batch import method. Full code: 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;
}

It only scans one level of the file directory, unlike the blog batch import which recursively walks all subdirectories

Because images don't have a hierarchical structure

This method finally returns the list of imported images

Imported images are copied to StarBlog.Web/wwwroot/assets/photography

It's not written in a separate Project like the blog import because this feature needs to be called via an API (actually the blog import needs that too; I'll integrate it into blogService later)

Controller

To wrap things up, I'll also paste the API code

/// <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}张图片"
    };
}

After import completes, the API returns the list of images

Results

Just kidding… no images in this part. There will be some in the next article when I cover the image waterfall layout~

_EOF_

StarBlog Blog Development Notes (9): Batch Importing Images

本文作者:
程序设计实验室
版权声明:
本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

相关文章

StarBlog博客开发笔记(24):统一接口数据返回格式

前言 开发接口,是给客户端(Web前端、App)用的,前面说的RESTFul,是接口的规范,有了统一的接口风格,客户端开发人员在访问后端功能的时候能更快找到需要的接口,能写出可维护性更高的代码。 而接口的数据返回格式也是接口规范的重要一环,不然一个接口返回JSON,一个返回纯字符串,客户端对接到数据时一脸懵逼,没法处理啊。 合格的接口返回值应该包括状态码、提示信息和数据。 就像这样: { st

2023-01-02 · StarBlog博客开发笔记 · 约 1 分钟

StarBlog博客开发笔记(19):Markdown渲染方案探索

前言 笔者认为,一个博客网站,最核心的是阅读体验。 在开发StarBlog的过程中,最耗时的恰恰也是文章的展示部分功能。 最开始还没研究出来如何很好的使用后端渲染,所以只能先用Editor.md组件做前端渲染,过渡一下。前端渲染我是不满意的,因为性能较差,页面加载出来还会闪一下,有割裂感,影响体验。 现在我已经做出了比较完善的后端渲染方案,前端渲染就可以直接退休了。本文介绍StarBlog博客开发

2022-10-28 · StarBlog博客开发笔记 · 约 1 分钟

讨论

共 0 条

良言一句三冬暖,恶语伤人六月寒。

加载评论中…