Skip to content

Commit

Permalink
🔧 优化图库界面
Browse files Browse the repository at this point in the history
  • Loading branch information
Redns committed Apr 16, 2022
1 parent b5a5522 commit bd16608
Show file tree
Hide file tree
Showing 14 changed files with 245 additions and 267 deletions.
60 changes: 21 additions & 39 deletions Blazor-Server/Common/FileOperator.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using ImageBed.Data.Entity;
using System.IO.Compression;
using SkiaSharp;
using static ImageBed.Common.UnitNameGenerator;

namespace ImageBed.Common
Expand All @@ -17,23 +16,27 @@ public static async Task CompressMulti(IEnumerable<string> srcFilepaths, string

try
{
string ExportTempDir = $"{GlobalValues.appSetting.Data.Resources.Images.Path}/ExportTempDir";
if (Directory.Exists(ExportTempDir))
{
Directory.Delete(ExportTempDir, true);
}
var imageConfig = GlobalValues.appSetting.Data.Resources.Images;
string ExportTempDir = $"{imageConfig.Path}/ExportTempDir";

// 创建文件夹用于存储导出文件
Directory.CreateDirectory(ExportTempDir);

// 添加所有导入文件至文件夹
foreach(string srcFilepath in srcFilepaths)
{
var srcFileName = srcFilepath.Split("/").Last();
using(var fileReadStream = new FileStream(srcFilepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
await SaveFile(fileReadStream, $"{ExportTempDir}/{srcFileName}");
_ = fileReadStream.FlushAsync();
}
}

// 压缩文件夹
ZipFile.CreateFromDirectory(ExportTempDir, zipFilepath);

// 删除文件夹
Directory.Delete(ExportTempDir, true);
}
catch (Exception ex)
Expand Down Expand Up @@ -75,15 +78,10 @@ public static void DeCompressMulti(string zipPath, string targetPath)
/// <returns></returns>
public static async Task SaveFile(Stream fileReader, string dstPath)
{
if (File.Exists(dstPath))
{
File.Delete(dstPath);
}

using (FileStream fileWriter = File.Create(dstPath))
{
await fileReader.CopyToAsync(fileWriter);
await fileReader.FlushAsync();
await fileWriter.FlushAsync();
}
}

Expand All @@ -109,7 +107,6 @@ public static async Task<ImageEntity> SaveImage(Stream imageReadStream, string i
{
await imageReadStream.CopyToAsync(imageWriteStream);
await imageWriteStream.FlushAsync();
await imageReadStream.FlushAsync();
}

ImageEntity imageInfo;
Expand All @@ -119,6 +116,7 @@ public static async Task<ImageEntity> SaveImage(Stream imageReadStream, string i
using (var thumbnailImage = image.ThumbnailImage(180))
{
thumbnailImage.WriteToFile($"{imageDir}/thumbnails_{unitImageName}");
thumbnailImage.Close();
}

// 构造图片信息
Expand All @@ -132,7 +130,10 @@ public static async Task<ImageEntity> SaveImage(Stream imageReadStream, string i
UploadTime = DateTime.Now.ToString(),
Owner = "Admin"
};

image.Close();
}

return imageInfo;
}

Expand All @@ -150,17 +151,10 @@ public static async Task<List<ImageEntity>> ImportImages(string zipFullPath, str
{
if(GetFileType(GetFileExtension(zipFullPath) ?? "") == FileType.COMPRESS)
{
// 创建临时文件夹
// 创建临时文件夹, 存储解压后的图片
// 这里不直接解压至 Images 文件夹下, 是为了方便导入图片信息至数据库
string tempDir = $"{importDir}/Temp";
if (!Directory.Exists(importDir))
{
Directory.CreateDirectory(importDir);
Directory.CreateDirectory(tempDir);
}
else if (!Directory.Exists(tempDir))
{
Directory.CreateDirectory(tempDir);
}
Directory.CreateDirectory(tempDir);

// 解压压缩包
// 录入解压出的所有图片信息, 并将其移动至 importDir 文件夹下
Expand All @@ -174,11 +168,14 @@ public static async Task<List<ImageEntity>> ImportImages(string zipFullPath, str
using (var imageReadStream = new FileStream(tempFileFullpath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
images.Add(await SaveImage(imageReadStream, tempFileName, importDir));
_ = imageReadStream.FlushAsync();
}
}
}
Directory.Delete(tempDir, true);

// 删除解压文件夹、压缩包文件
File.Delete(zipFullPath);
Directory.Delete(tempDir, true);
}
else
{
Expand All @@ -191,20 +188,5 @@ public static async Task<List<ImageEntity>> ImportImages(string zipFullPath, str
}
return images;
}


public static void ScaleImage(string imagePath, int height=0, int width=0, int quality=0)
{
using(var input = File.OpenRead(imagePath))
{
using(var inputStream = new SKManagedStream(input))
{
using (var origin = SKBitmap.Decode(inputStream))
{

}
}
}
}
}
}
9 changes: 3 additions & 6 deletions Blazor-Server/Common/UnitNameGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -195,12 +195,9 @@ public enum RenameFormat
/// <returns></returns>
public static string RenameFile(string dir, string srcName, RenameFormat format)
{
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
Directory.CreateDirectory(dir);

if(format == RenameFormat.NONE) { return srcName; }
if (format == RenameFormat.NONE) { return srcName; }
string dstName = format switch
{
RenameFormat.MD5 => EncryptAndDecrypt.Encrypt_MD5(srcName),
Expand All @@ -214,7 +211,7 @@ public static string RenameFile(string dir, string srcName, RenameFormat format)
};
dstName += $".{GetFileExtension(srcName)}";

if (File.Exists(dstName))
if ((format != RenameFormat.NONE) && File.Exists(dstName))
{
dstName = RenameFile(dir, dstName, format);
return dstName;
Expand Down
81 changes: 43 additions & 38 deletions Blazor-Server/Controllers/ImageController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,33 @@ public class ImageController : ControllerBase
/// <summary>
/// 上传图片
/// </summary>
/// <param name="token">用户令牌</param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<object>> Post([FromForm] IFormCollection formCollection)
{
List<string> imageUrls = new();
List<ImageEntity> images = new();
var imageConfig = GlobalValues.appSetting.Data.Resources.Images;

List<string> imageUrls = new(); // 图片url(相对路径)
List<ImageEntity> images = new(); // 图片信息

GlobalValues.Logger.Info("Uploading images...");

try
{
GlobalValues.Logger.Info("Uploading images...");
using (var context = new OurDbContext())
{
// 获取图片存储路径
// 若文件夹不存在则创建
string imageDir = $"{GlobalValues.appSetting?.Data?.Resources?.Images?.Path}";
if (!Directory.Exists(imageDir))
{
Directory.CreateDirectory(imageDir);
}
string imageDir = $"{imageConfig.Path}";
Directory.CreateDirectory(imageDir);

var sqlImageData = new SQLImageData(context);
var uploadImages = (FormFileCollection)formCollection.Files;

var imageMaxNumLimit = GlobalValues.appSetting?.Data?.Resources?.Images?.MaxNum ?? 0;
if((imageMaxNumLimit > 0) && (uploadImages.Count > imageMaxNumLimit))
// 检查上传图片是否满足数量限制
if((imageConfig.MaxNum > 0) && (uploadImages.Count > imageConfig.MaxNum))
{
int indexStart = imageMaxNumLimit;
int indexCount = uploadImages.Count - imageMaxNumLimit;
int indexStart = imageConfig.MaxNum;
int indexCount = uploadImages.Count - imageConfig.MaxNum;
uploadImages.RemoveRange(indexStart, indexCount);
}

Expand All @@ -52,12 +50,14 @@ public async Task<ApiResult<object>> Post([FromForm] IFormCollection formCollect
{
if (GetFileType(GetFileExtension(fileReader.FileName) ?? "") == FileType.COMPRESS)
{
// 上传文件为压缩包
GlobalValues.Logger.Info("Importing images...");

string importFullPath = $"{imageDir}/Import.zip";
using(var fileReadStream = fileReader.OpenReadStream())
{
await FileOperator.SaveFile(fileReadStream, importFullPath);
_ = fileReadStream.FlushAsync();
}

foreach(var image in await FileOperator.ImportImages(importFullPath, imageDir))
Expand All @@ -68,13 +68,13 @@ public async Task<ApiResult<object>> Post([FromForm] IFormCollection formCollect
}
else
{
int imageMaxSizeLimit = GlobalValues.appSetting.Data.Resources.Images.MaxSize;
if((imageMaxSizeLimit <= 0) || fileReader.Length <= imageMaxSizeLimit*1024*1024)
if((imageConfig.MaxSize <= 0) || fileReader.Length <= imageConfig.MaxSize * 1024*1024)
{
ImageEntity image;
using(var imageReader = fileReader.OpenReadStream())
using(var imageReadStream = fileReader.OpenReadStream())
{
image = await FileOperator.SaveImage(imageReader, fileReader.FileName, imageDir);
image = await FileOperator.SaveImage(imageReadStream, fileReader.FileName, imageDir);
await imageReadStream.FlushAsync();
}
images.Add(image);
imageUrls.Add($"{image.Url}");
Expand All @@ -87,8 +87,8 @@ public async Task<ApiResult<object>> Post([FromForm] IFormCollection formCollect
}
catch (Exception)
{
GlobalValues.Logger.Error($"Upload failed, imageName: {fileReader.FileName}");
imageUrls.Add(string.Empty);
GlobalValues.Logger.Error($"Upload failed, imageName: {fileReader.FileName}");
}
}
await sqlImageData.AddRangeAsync(images);
Expand Down Expand Up @@ -116,12 +116,12 @@ public async Task<IActionResult> Get(string imageName)
// 构造图片路径
// 图片存储路径为 Data/Resources/Images
// 当图片不存在时返回 "imageNotFound.jpg"
string imageDir = GlobalValues.appSetting?.Data?.Resources?.Images?.Path ?? string.Empty;
string imageFullPath = $"{imageDir}/{imageName}";
var imageConfig = GlobalValues.appSetting.Data.Resources.Images;
string imageFullPath = $"{imageConfig.Path}/{imageName}";
string imageExtension = GetFileExtension(imageName) ?? string.Empty;
if (!System.IO.File.Exists(imageFullPath))
{
return File(System.IO.File.ReadAllBytes($"{imageDir}/imageNotFound.jpg"), $"image/{imageExtension}");
return File(System.IO.File.ReadAllBytes($"{imageConfig.Path}/imageNotFound.jpg"), $"image/{imageExtension}");
}
else
{
Expand Down Expand Up @@ -162,27 +162,32 @@ public async Task<ApiResult<object>> Delete(string imageName)
GlobalValues.Logger.Info($"Del image {imageName}");

// 删除磁盘上的文件
string? imageFullPath = $"{GlobalValues.appSetting?.Data?.Resources?.Images?.Path}/{imageName}";
string? imageThumbnailsFullPath = $"{GlobalValues.appSetting?.Data?.Resources?.Images?.Path}/thumbnails_{imageName}";
if (System.IO.File.Exists(imageFullPath))
{
System.IO.File.Delete(imageFullPath);
}
if (System.IO.File.Exists(imageThumbnailsFullPath))
{
System.IO.File.Delete(imageThumbnailsFullPath);
}
var imageConfig = GlobalValues.appSetting.Data.Resources.Images;
string? imageFullPath = $"{imageConfig.Path}/{imageName}";
string? imageThumbnailsFullPath = $"{imageConfig.Path}/thumbnails_{imageName}";

// 删除数据库信息
using (var context = new OurDbContext())
try
{
var sqlImageData = new SQLImageData(context);
var image = await sqlImageData.GetAsync(ImageFilter.NAME, imageName);
if(image != null)
// 删除磁盘文件
if (System.IO.File.Exists(imageFullPath)) { System.IO.File.Delete(imageFullPath); }
if (System.IO.File.Exists(imageThumbnailsFullPath)) { System.IO.File.Delete(imageThumbnailsFullPath); }

// 删除数据库信息
using (var context = new OurDbContext())
{
await sqlImageData.RemoveAsync(image);
var sqlImageData = new SQLImageData(context);
var image = await sqlImageData.GetAsync(ImageFilter.NAME, imageName);
if (image != null)
{
await sqlImageData.RemoveAsync(image);
}
}
}
catch (Exception ex)
{
GlobalValues.Logger.Error($"Del image failed, {ex.Message}");
}

return new ApiResult<object>(200, "Delete image success", null);
}
}
Expand Down
18 changes: 7 additions & 11 deletions Blazor-Server/Data/Access/OurDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ public bool Remove(ImageEntity image)
/// </summary>
/// <param name="images">待移除的图片列表</param>
/// <returns>移除成功返回true, 否则返回false</returns>
public async Task<bool> RemoveRangeAsync(List<ImageEntity> images)
public async Task<bool> RemoveRangeAsync(IEnumerable<ImageEntity> images)
{
if ((_context != null) && (_context.Images != null))
{
Expand All @@ -307,19 +307,15 @@ public async Task<bool> RemoveRangeAsync(List<ImageEntity> images)
foreach(var image in images)
{
// 删除磁盘上的文件
string? imageFullPath = $"{GlobalValues.appSetting?.Data?.Resources?.Images?.Path}/{image.Name}";
string? imageThumbnailsFullPath = $"{GlobalValues.appSetting?.Data?.Resources?.Images?.Path}/thumbnails_{image.Name}";
if (File.Exists(imageFullPath))
{
File.Delete(imageFullPath);
}
if (File.Exists(imageThumbnailsFullPath))
{
File.Delete(imageThumbnailsFullPath);
}
string? imageFullPath = $"{imageDir}/{image.Name}";
string? imageThumbnailsFullPath = $"{imageDir}/thumbnails_{image.Name}";
if (File.Exists(imageFullPath)) { File.Delete(imageFullPath); }
if (File.Exists(imageThumbnailsFullPath)) { File.Delete(imageThumbnailsFullPath); }
}

_context.Images.RemoveRange(images);
await _context.SaveChangesAsync();

return true;
}
catch (Exception ex)
Expand Down
Binary file modified Blazor-Server/Data/Database/imagebed.sqlite
Binary file not shown.
3 changes: 2 additions & 1 deletion Blazor-Server/Data/Entity/AppSetting.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using ImageBed.Common;
using ImageBed.Pages;
using Newtonsoft.Json;
using static ImageBed.Common.UnitNameGenerator;

Expand Down Expand Up @@ -94,7 +95,7 @@ public class Resource

public class Pics
{
public bool ViewList { get; set; }
public ViewFormat ViewFormat { get; set; }
}


Expand Down
Binary file removed Blazor-Server/Data/Resources/Images/THZP4N80.png
Binary file not shown.
2 changes: 0 additions & 2 deletions Blazor-Server/ImageBed.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,10 @@
<PackageReference Include="AntDesign" Version="0.10.5" />
<PackageReference Include="AntDesign.Charts" Version="0.2.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.3" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.14.0" />
<PackageReference Include="NetVips" Version="2.1.0" />
<PackageReference Include="NetVips.Native" Version="8.12.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="NLog.Web.AspNetCore" Version="4.14.0" />
<PackageReference Include="SkiaSharp" Version="2.80.3" />
</ItemGroup>

<ItemGroup>
Expand Down
6 changes: 3 additions & 3 deletions Blazor-Server/Pages/Cog.razor
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,9 @@
OnFinishFailed="OnFinishFailed"
Style="margin-top:80px;">
<FormItem Label="默认视图">
<RadioGroup @bind-Value=@picsConfig.ViewList>
<Radio RadioButton Value="@true">表 格</Radio>
<Radio RadioButton Value="@false">卡 片</Radio>
<RadioGroup @bind-Value=@picsConfig.ViewFormat>
<Radio RadioButton Value="@ViewFormat.List">表 格</Radio>
<Radio RadioButton Value="@ViewFormat.Card">卡 片</Radio>
</RadioGroup>
</FormItem>
<FormItem WrapperColOffset="8" WrapperColSpan="16">
Expand Down
Loading

0 comments on commit bd16608

Please sign in to comment.