这篇文章主要为大家介绍了.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。
所以我将项目中原先使用 System.Drawing.Imaging 实现的方法采用 SkiaSharp 进行了重写。SkiaSharp是 Google 的Skia 图形库的 .NET 包装器,可用于跨移动、服务器和桌面平台绘制 2D 图形。SkiaSharp 可与 OpenGL 一起用于硬件加速渲染。SkiaSharp 最初由 Mono 开发,但现在由 Microsoft 维护,并根据MIT License提供。
SkiaSharpSkiaSharp.NativeAssets.LinuxSkiaSharp.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 生成二维码和图形验证码及图片进行指定区域截取方法实现 就讲解完了