个人博客-给图片添加水印

前言

🤔🤔🤔

需要用到的库

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})">

效果图

微信截图_20230705185107

关键代码源码地址

personalblog/Personalblog/Apis/PicLibController.cs at master · ZyPLJ/personalblog · GitHub

参考资料