个人博客-给图片添加水印
前言
🤔🤔🤔
需要用到的库
SixLabors.lmageSharp 2.1.3
SixLabors.lmageSharp.Web 2.0.2
SixLabors.Fonts 1.0.0-beta19
SixLabors.lmageSharp.Drawing 1.0.0-beta15
注意:该项目为.NET6 Core项目
开始实现
首先需要有Image
对象和IImageFormat
对象,可以通过以下代码获取:
//imagePath 图片路径
await using var fileStream = new FileStream(imagePath, FileMode.Open);
var (image, format) = await Image.LoadWithFormatAsync(fileStream);
//调用
await GenerateImageResponse(image,format)
注意:如果部署到liunx系统上,记得修改字体~
方法一 直接使用DrawText添加水印
然后就可以写返回图片流的接口了,如下:
private static async Task<IActionResult> GenerateImageResponse(Image image, IImageFormat format)
{
//获取图像的编码器,用于保存图像到流中
var encoder = image.GetConfiguration().ImageFormatsManager.FindEncoder(format);
//创建一个内存流来保存图像数据 using语法可以确保在使用完流后自动释放资源。
await using var stream = new MemoryStream();
//设置字体和大小
var font = SystemFonts.CreateFont("Arial", 50);
//定义水印的位置
var location = new PointF(image.Width - 250, image.Height - 100);
//添加水印
image.Mutate(ctx => ctx.DrawText("ZY blog", font, new Rgba32(255, 255, 255, 128), location));
//将修改后的图像保存到流中
await image.SaveAsync(stream, encoder);
//返回图片流
return new FileContentResult(stream.GetBuffer(), "image/jpeg");
}
方法二 使用图像叠加添加水印
有些图片在处理之前格式不支持透明度,所以有些图片无法加载有透明度的水印,那么可以使用图片叠加技术,在原有图像的基础上叠加一层水印图像,代码实现如下:
private static async Task<IActionResult> GenerateImageResponse(Image image, IImageFormat format)
{
var encoder = image.GetConfiguration().ImageFormatsManager.FindEncoder(format);
await using var stream = new MemoryStream();
// 创建水印图像
var watermarkImage = new Image<Rgba32>(image.Width, image.Height);
watermarkImage.Mutate(x => x.BackgroundColor(Rgba32.Transparent));
//参数与上面一致
var font = SystemFonts.CreateFont("Arial", 50, FontStyle.Bold);
var location = new PointF(watermarkImage.Width - 250, watermarkImage.Height - 100);
watermarkImage.Mutate(x => x.DrawText("ZY blog", font, new Rgba32(255, 255, 255, 128), location));
// 将水印图像与原始图像叠加
image.Mutate(x => x.DrawImage(watermarkImage, 1f));
image.Save(stream, encoder);
return new FileContentResult(stream.GetBuffer(), "image/jpeg");
}
该方法对比第一种方法多了一个水印图层,可能会导致一些性能损失,根据实际情况选择即可。
使用方法
前端调用写好的接口即可:
[HttpGet("Random/{width:int}/{height:int}")]
public async Task<IActionResult> GetRandomImage(int width,int height)
{
var (image,format) = await _service.GetRandomImageAsync(width,height);
return await GenerateImageResponse(image,format);
}
<img class="bd-placeholder-img" alt="" style="width:200px;height: 250px"
src="@Url.Action("GetRandomImage", "PicLib" ,new { seed = post.Id,Width = 800, Height = 1000})">
效果图
关键代码源码地址
personalblog/Personalblog/Apis/PicLibController.cs at master · ZyPLJ/personalblog · GitHub