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
目录8 个章节
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: StarBlog - (5) Starting to Build the Web Project
-
Developing a Blog Project with .NetCore: StarBlog - (6) Page Development: Blog Post List
-
Developing a Blog Project with .NetCore: StarBlog - (7) Page Development: Post Detail Page
-
Developing a Blog Project with .NetCore: StarBlog - (8) Displaying the Category Hierarchy
-
Developing a Blog Project with .NetCore: StarBlog - (9) Batch Importing Images
-
...
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博客开发笔记(3):模型设计
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetCore开发博客项目 StarBlog - (3) 模型设计 ... 基于.NetCore开发博客项目 StarBlog - 接口返回值包装 基于.NetCore开发博客项目 StarBlog - 上传
2022-04-22 · StarBlog博客开发笔记 · 约 1 分钟
StarBlog博客开发笔记(10):图片展示-瀑布流-首页卡片
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetCore开发博客项目 StarBlog - (3) 模型设计 基于.NetCore开发博客项目 StarBlog - (4) markdown博客批量导入 基于.NetCore开发博客项目 StarBl
2022-11-22 · StarBlog博客开发笔记 · 约 1 分钟
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 条加载评论中…