温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

.NET SkiaSharp如何生成二维码验证码及指定区域截取

发布时间:2022-10-14 09:50:04 来源:亿速云 阅读:188 作者:iii 栏目:开发技术

本文小编为大家详细介绍“.NET SkiaSharp如何生成二维码验证码及指定区域截取”,内容详细,步骤清晰,细节处理妥当,希望这篇“.NET SkiaSharp如何生成二维码验证码及指定区域截取”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

正文

在最新版的 .NET 平台中,微软在逐步放弃 System.Drawing.Imaging ,给出的理由如下:

System.Drawing命名空间对某些操作系统和应用程序类型有一些限制。

在Windows, System.Drawing 依赖于GDI+操作系统附带的本机库。 某些Windows SKUS Windows Server Core 或 Windows Nano)不包含此本机库作为 OS 的一部分。 如果使用此命名空间并且无法加载库,则运行时将引发异常。

命名空间中的某些类型依赖于 GDI+ ,而 Windows 服务以及 ASP.NET Core 和 System.Drawing ASP.NET 应用不支持。 这些类型在System.Drawing.Common NuGet包中,并包括 System.Drawing.Bitmap 和 System.Drawing.Font 。 但是,命名空间中的基元类型(如 System.Drawing.Color 、、 和 System.Drawing.Size System.Drawing.Point System.Drawing.Rectangle )可以在任何应用程序中使用。

在 .NET 5 和早期版本中,System.Drawing.Common NuGet 包适用于 Windows、Linux 和 macOS。 但是,存在一些平台差异。 在 Linux 和 macOS 上,GDI+功能由libgdiplus) 库实现。 默认情况下,大多数 Linux 发行版中不会安装此库,也不支持 GDI+ 和 macOS 上Windows的所有功能。 还有一些平台,其中 libgdiplus 完全不可用。 若要在 Linux 和 macOS 上使用 System.Drawing.Common 包中的类型,必须单独安装 libgdiplus。 有关详细信息,请参阅在Linux 上安装 .NET或在macOS 上安装 .NET。

在 .NET 6 及更高版本中,System.Drawing.Common NuGet 包仅在 Windows操作系统上受支持。 有关详细信息,请参阅 仅支持System.Drawing.Common Windows。

SkiaSharp是 Google 的Skia 图形库的 .NET 包装器,可用于跨移动、服务器和桌面平台绘制 2D 图形。SkiaSharp 可与 OpenGL 一起用于硬件加速渲染。SkiaSharp 最初由 Mono 开发,但现在由 Microsoft 维护,并根据MIT License提供。

依赖的 Nuget 组件如下

  • SkiaSharp

  • SkiaSharp.NativeAssets.Linux

  • SkiaSharp.QrCode

using SkiaSharp.QrCode;
namespace Common
{
    public class ImgHelper
    {
        /// <summary>
        /// 生成二维码
        /// </summary>
        /// <param name="text">二维码内容</param>
        /// <returns></returns>
        public static byte[] GetQrCode(string text)
        {
            using QRCodeGenerator generator = new();
            using var qr = generator.CreateQrCode(text, ECCLevel.L);
            SKImageInfo info = new(500, 500);
            using var surface = SKSurface.Create(info);
            using var canvas = surface.Canvas;
            canvas.Render(qr, info.Width, info.Height, SKColors.White, SKColors.Black);
            using var image = surface.Snapshot();
            using var data = image.Encode(SKEncodedImageFormat.Png, 100);
            return data.ToArray();
        }
        /// <summary>
        /// 从图片截取部分区域
        /// </summary>
        /// <param name="fromImagePath">源图路径</param>
        /// <param name="offsetX">距上</param>
        /// <param name="offsetY">距左</param>
        /// <param name="width">宽度</param>
        /// <param name="height">高度</param>
        /// <returns></returns>
        public static byte[] Screenshot(string fromImagePath, int offsetX, int offsetY, int width, int height)
        {
            using var original = SKBitmap.Decode(fromImagePath);
            using SKBitmap bitmap = new(width, height);
            using SKCanvas canvas = new(bitmap);
            SKRect sourceRect = new(offsetX, offsetY, offsetX + width, offsetY + height);
            SKRect destRect = new(0, 0, width, height);
            canvas.DrawBitmap(original, sourceRect, destRect);
            using var img = SKImage.FromBitmap(bitmap);
            using SKData p = img.Encode(SKEncodedImageFormat.Png, 100);
            return p.ToArray();
        }
        /// <summary>
        /// 获取图像数字验证码
        /// </summary>
        /// <param name="text">验证码内容,如4为数字</param>
        /// <returns></returns>
        public static byte[] GetVerifyCode(string text)
        {
            int width = 128;
            int height = 45;
            Random random = new();
            //创建bitmap位图
            using SKBitmap image = new(width, height, SKColorType.Bgra8888, SKAlphaType.Premul);
            //创建画笔
            using SKCanvas canvas = new(image);
            //填充背景颜色为白色
            canvas.DrawColor(SKColors.White);
            //画图片的背景噪音线
            for (int i = 0; i < (width * height * 0.015); i++)
            {
                using SKPaint drawStyle = new();
                drawStyle.Color = new(Convert.ToUInt32(random.Next(Int32.MaxValue)));
                canvas.DrawLine(random.Next(0, width), random.Next(0, height), random.Next(0, width), random.Next(0, height), drawStyle);
            }
            //将文字写到画布上
            using (SKPaint drawStyle = new())
            {
                drawStyle.Color = SKColors.Red;
                drawStyle.TextSize = height;
                drawStyle.StrokeWidth = 1;
                float emHeight = height - (float)height * (float)0.14;
                float emWidth = ((float)width / text.Length) - ((float)width * (float)0.13);
                canvas.DrawText(text, emWidth, emHeight, drawStyle);
            }
            //画图片的前景噪音点
            for (int i = 0; i < (width * height * 0.6); i++)
            {
                image.SetPixel(random.Next(0, width), random.Next(0, height), new SKColor(Convert.ToUInt32(random.Next(Int32.MaxValue))));
            }
            using var img = SKImage.FromBitmap(image);
            using SKData p = img.Encode(SKEncodedImageFormat.Png, 100);
            return p.ToArray();
        }
    }
}

项目如果是在 windows 服务器下运行则不需要任何安装任何依赖项,如果是在 linux 服务下运行则需要安装 libfontconfig1,如 ubuntu 的安装命令

apt-get update

apt-get -y install libfontconfig1

如果是采用 docker 模式运行,则需要在 dockerfile 中添加如下配置,该命令适用于 debian 和 ubuntu 的 docker

RUN apt-get update && apt-get -y install libfontconfig1

读到这里,这篇“.NET SkiaSharp如何生成二维码验证码及指定区域截取”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI