ToB企服应用市场:ToB评测及商务社交产业平台

标题: .NET 采用 SkiaSharp 生成二维码和图形验证码及图片进行指定区域截取方法实 [打印本页]

作者: 知者何南    时间: 2022-10-12 22:53
标题: .NET 采用 SkiaSharp 生成二维码和图形验证码及图片进行指定区域截取方法实
在最新版的 .NET 平台中,微软在逐步放弃 System.Drawing.Imaging ,给出的理由如下:
System.Drawing命名空间对某些操作系统和应用程序类型有一些限制。
所以我将项目中原先使用 System.Drawing.Imaging 实现的方法采用 SkiaSharp 进行了重写。
SkiaSharp是 Google 的Skia 图形库的 .NET 包装器,可用于跨移动、服务器和桌面平台绘制 2D 图形。SkiaSharp 可与 OpenGL 一起用于硬件加速渲染。SkiaSharp 最初由 Mono 开发,但现在由 Microsoft 维护,并根据MIT License提供。
依赖的 Nuget 组件如下:
  1. using SkiaSharp.QrCode;
  2. namespace Common
  3. {
  4.     public class ImgHelper
  5.     {
  6.         /// <summary>
  7.         /// 生成二维码
  8.         /// </summary>
  9.         /// <param name="text">二维码内容</param>
  10.         /// <returns></returns>
  11.         public static byte[] GetQrCode(string text)
  12.         {
  13.             using QRCodeGenerator generator = new();
  14.             using var qr = generator.CreateQrCode(text, ECCLevel.L);
  15.             SKImageInfo info = new(500, 500);
  16.             using var surface = SKSurface.Create(info);
  17.             using var canvas = surface.Canvas;
  18.             canvas.Render(qr, info.Width, info.Height, SKColors.White, SKColors.Black);
  19.             using var image = surface.Snapshot();
  20.             using var data = image.Encode(SKEncodedImageFormat.Png, 100);
  21.             return data.ToArray();
  22.         }
  23.         /// <summary>
  24.         /// 从图片截取部分区域
  25.         /// </summary>
  26.         /// <param name="fromImagePath">源图路径</param>
  27.         /// <param name="offsetX">距上</param>
  28.         /// <param name="offsetY">距左</param>
  29.         /// <param name="width">宽度</param>
  30.         /// <param name="height">高度</param>
  31.         /// <returns></returns>
  32.         public static byte[] Screenshot(string fromImagePath, int offsetX, int offsetY, int width, int height)
  33.         {
  34.             using var original = SKBitmap.Decode(fromImagePath);
  35.             using SKBitmap bitmap = new(width, height);
  36.             using SKCanvas canvas = new(bitmap);
  37.             SKRect sourceRect = new(offsetX, offsetY, offsetX + width, offsetY + height);
  38.             SKRect destRect = new(0, 0, width, height);
  39.             canvas.DrawBitmap(original, sourceRect, destRect);
  40.             using var img = SKImage.FromBitmap(bitmap);
  41.             using SKData p = img.Encode(SKEncodedImageFormat.Png, 100);
  42.             return p.ToArray();
  43.         }
  44.         /// <summary>
  45.         /// 获取图像数字验证码
  46.         /// </summary>
  47.         /// <param name="text">验证码内容,如4为数字</param>
  48.         /// <returns></returns>
  49.         public static byte[] GetVerifyCode(string text)
  50.         {
  51.             int width = 128;
  52.             int height = 45;
  53.             Random random = new();
  54.             //创建bitmap位图
  55.             using SKBitmap image = new(width, height, SKColorType.Bgra8888, SKAlphaType.Premul);
  56.             //创建画笔
  57.             using SKCanvas canvas = new(image);
  58.             //填充背景颜色为白色
  59.             canvas.DrawColor(SKColors.White);
  60.             //画图片的背景噪音线
  61.             for (int i = 0; i < (width * height * 0.015); i++)
  62.             {
  63.                 using SKPaint drawStyle = new();
  64.                 drawStyle.Color = new(Convert.ToUInt32(random.Next(Int32.MaxValue)));
  65.                 canvas.DrawLine(random.Next(0, width), random.Next(0, height), random.Next(0, width), random.Next(0, height), drawStyle);
  66.             }
  67.             //将文字写到画布上
  68.             using (SKPaint drawStyle = new())
  69.             {
  70.                 drawStyle.Color = SKColors.Red;
  71.                 drawStyle.TextSize = height;
  72.                 drawStyle.StrokeWidth = 1;
  73.                 float emHeight = height - (float)height * (float)0.14;
  74.                 float emWidth = ((float)width / text.Length) - ((float)width * (float)0.13);
  75.                 canvas.DrawText(text, emWidth, emHeight, drawStyle);
  76.             }
  77.             //画图片的前景噪音点
  78.             for (int i = 0; i < (width * height * 0.6); i++)
  79.             {
  80.                 image.SetPixel(random.Next(0, width), random.Next(0, height), new SKColor(Convert.ToUInt32(random.Next(Int32.MaxValue))));
  81.             }
  82.             using var img = SKImage.FromBitmap(image);
  83.             using SKData p = img.Encode(SKEncodedImageFormat.Png, 100);
  84.             return p.ToArray();
  85.         }
  86.     }
  87. }
复制代码
项目如果是在 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 生成二维码和图形验证码及图片进行指定区域截取方法实现 就讲解完了,有任何不明白的,可以在文章下面评论或者私信我,欢迎大家积极的讨论交流,有兴趣的朋友可以关注我目前在维护的一个 .NET 基础框架项目,项目地址如下
https://github.com/berkerdong/NetEngine.git
https://gitee.com/berkerdong/NetEngine.git

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4