feat: use lossless compression when size is under 128KB.

This commit is contained in:
jackfiled 2025-03-25 14:55:39 +08:00
parent fda4c01c22
commit 3b88dfd107
2 changed files with 31 additions and 8 deletions

View File

@ -0,0 +1,12 @@
namespace YaeBlog.Core.Exceptions;
public class BlogCommandException : Exception
{
public BlogCommandException(string message) : base(message)
{
}
public BlogCommandException(string message, Exception innerException) : base(message, innerException)
{
}
}

View File

@ -56,7 +56,7 @@ public sealed class ImageCompressService(IEssayScanService essayScanService, ILo
}
CompressResult[] compressedImages = (await Task.WhenAll(from image in uncompressedImages
select Task.Run(async () => new CompressResult(image, await ConvertToWebp(image.Content))))).ToArray();
select Task.Run(async () => new CompressResult(image, await ConvertToWebp(image))))).ToArray();
compressedSize += compressedImages.Select(i => i.CompressContent.Length).Sum();
@ -65,7 +65,8 @@ public sealed class ImageCompressService(IEssayScanService essayScanService, ILo
select r.ImageInfo with
{
File = new FileInfo(r.ImageInfo.File.FullName.Split('.')[0] + ".webp"),
Content = r.CompressContent
Content = r.CompressContent,
MineType = "image/webp"
}).ToList();
// 修改文本
string blogContent = compressedImages.Aggregate(content.Content, (c, r) =>
@ -88,21 +89,31 @@ public sealed class ImageCompressService(IEssayScanService essayScanService, ILo
}
}
private static async Task<byte[]> ConvertToWebp(byte[] image)
private static async Task<byte[]> ConvertToWebp(BlogImageInfo image)
{
using ImageJob job = new();
BuildJobResult result = await job.Decode(MemorySource.Borrow(image))
BuildJobResult result = await job.Decode(MemorySource.Borrow(image.Content))
.Branch(f => f.EncodeToBytes(new WebPLosslessEncoder()))
.EncodeToBytes(new WebPLossyEncoder(75))
.Finish()
.InProcessAsync();
ArraySegment<byte>? array = result.First?.TryGetBytes();
// 超过128KB的图片使用有损压缩
// 反之使用无损压缩
if (array.HasValue)
ArraySegment<byte>? losslessImage = result.TryGet(1)?.TryGetBytes();
ArraySegment<byte>? lossyImage = result.TryGet(2)?.TryGetBytes();
if (image.Size <= 128 * 1024 && losslessImage.HasValue)
{
return array.Value.ToArray();
return losslessImage.Value.ToArray();
}
throw new BlogFileException();
if (lossyImage.HasValue)
{
return lossyImage.Value.ToArray();
}
throw new BlogCommandException($"Failed to convert {image.File.Name} to webp format: return value is null.");
}
}