首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ASP.NET Core 给上传的图片加水印

ASP.NET Core 给上传的图片加水印

作者头像
Edi Wang
发布2019-07-08 19:16:20
2.8K0
发布2019-07-08 19:16:20
举报
文章被收录于专栏:汪宇杰博客汪宇杰博客

图片加水印是网站中使用非常广泛的技术,可以保护网站内容的版权,例如我博客这样的网站。在传统ASP.NET(.NET Framework)中,我们可以使用System.Web.Helpers.WebImage来添加水印,就像这样:

var image = new WebImage(imageBytes);
image.AddTextWatermark(
    Settings.Instance.WatermarkText, "White", Settings.Instance.WatermarkFontSize,
    opacity: Settings.Instance.WatermarkTextOpacityPercentage
    );

但是在.NET Core中,没有WebImage这个类型了。我们如何给图片加水印呢?

我们从图片上传开始。在ASP.NET Core中,我们用IFormFile来上传文件,也包括图片文件。需要详细了解可以参考微软官方文档:https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads?view=aspnetcore-2.1

在我的博客系统里,我写了一个Action用来上传图片,将图片文件塞到一个MemoryStream对象里,之后的图片存储服务就可以把它保存到目标位置

[Route("image/upload")]
public async Task<IActionResult> UploadImageAsync(IFormFile file)
{
...
    using (var stream = new MemoryStream())
    {
        await file.CopyToAsync(stream);
        ... // call underlying image storage service
    }
...
}

要添加水印,我们需要修改图片stream。

但是.NET Core默认情况下没有处理图片的能力,因为System.Drawing命名空间里的API是非常有限的。我们需要引用一个微软官方的NuGet包来引入我们在.NET Framework中曾经熟悉的那些API:

Install-Package System.Drawing.Common -Version 4.5.1

现在我们就可以访问System.Drawing.ImageSystem.Drawing.Graphics等API了。

下面的代码将会使用这些类型在上传的图片的stream上添加文字水印:

// Add watermark
var watermarkedStream = new MemoryStream();
using (var img = Image.FromStream(stream))
{
    using (var graphic = Graphics.FromImage(img))
    {
        var font = new Font(FontFamily.GenericSansSerif, 20, FontStyle.Bold, GraphicsUnit.Pixel);
        var color = Color.FromArgb(128, 255, 255, 255);
        var brush = new SolidBrush(color);
        var point = new Point(img.Width - 120, img.Height - 30);
        graphic.DrawString("edi.wang", font, brush, point);
        img.Save(watermarkedStream, ImageFormat.Png);
    }
}

结果就是这样的:

其中有一些要注意的地方:

1. 你不能更改原始stream,如果你尝试把图片存储覆盖原始stream的话,是不会有效果的,就像这样:

img.Save(stream, ImageFormat.Png);

这就是为啥我定义了另一个watermarkedStream对象。

2. 针对水印的位置,也就是point对象。我的计算方式是添加水印到图片右下角,你需要根据自己需要修改这个位置。

3. 我建议字体采用跨平台的字体,因为.NET Core不止能部署在Windows上。

最后,我博客里上传图片加水印的完整样例代码如下:

[Authorize]
[HttpPost]
[Route("image/upload")]
public async Task<IActionResult> UploadImageAsync(IFormFile file)
{
    try
    {
        if (null == file)
        {
            Logger.LogError("file is null.");
            return BadRequest();
        }
        if (file.Length > 0)
        {
            var name = Path.GetFileName(file.FileName);
            if (name != null)
            {
                using (var stream = new MemoryStream())
                {
                    await file.CopyToAsync(stream);
                    // Add watermark
                    var watermarkedStream = new MemoryStream();
                    using (var img = Image.FromStream(stream))
                    {
                        using (var graphic = Graphics.FromImage(img))
                        {
                            var font = new Font(FontFamily.GenericSansSerif, 20, FontStyle.Bold, GraphicsUnit.Pixel);
                            var color = Color.FromArgb(128, 255, 255, 255);
                            var brush = new SolidBrush(color);
                            var point = new Point(img.Width - 120, img.Height - 30);
                            graphic.DrawString("edi.wang", font, brush, point);
                            img.Save(watermarkedStream, ImageFormat.Png);
                        }
                    }
                    var response = await _imageStorageProvider.InsertAsync(name, watermarkedStream.ToArray());
                    Logger.LogInformation("Image Upload: " + JsonConvert.SerializeObject(response));
                    if (response.IsSuccess)
                    {
                        string refPath = "/uploads/" + response.Item;
                        return Json(new { location = refPath });
                    }
                    Logger.LogError(response.Message);
                    return StatusCode(StatusCodes.Status500InternalServerError);
                }
            }
        }
        return BadRequest();
    }
    catch (Exception e)
    {
        Logger.LogError(e, $"Error uploading image.");
        return StatusCode(StatusCodes.Status500InternalServerError);
    }
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-10-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 汪宇杰博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档