.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提供。
依赖的 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 生成二维码和图形验证码及图片进行指定区域截取方法实现 就讲解完了,有任何不明白的,可以在文章下面评论或者私信我,欢迎大家积极的讨论交流,有兴趣的朋友可以关注我目前在维护的一个 .NET 基础框架项目,项目地址如下
https://github.com/berkerdong/NetEngine.git
https://gitee.com/berkerdong/NetEngine.git
.NET 采用 SkiaSharp 生成二维码和图形验证码及图片进行指定区域截取方法实现的更多相关文章
- C# WPF使用ZXing生成二维码ImageSource
介绍: 如果需要实在WPF窗体程序中现类似如下的二维码图片生成功能,可以通过本文的方法实现 添加步骤: 1.在http://zxingnet.codeplex.com/站点上下载ZXing .Net的 ...
- jenkins 安卓打包生成二维码下载
先来张图看看吧 构思 jenkins gradle 打包apk文件,python myqr 模块生成二维码 放入nginx 访问图片的路径,apk安装包放在 nginx 下载目录. 环境 centos ...
- ASP.NET 生成二维码(采用ThoughtWorks.QRCode和QrCode.Net两种方式)
最近做项目遇到生成二维码的问题,发现网上用的最多的是ThoughtWorks.QRCode和QrCode.Net两种方式.访问官网看着例子写了两个Demo,使用过程中发现两个都挺好用的,Thought ...
- C#运用ThoughtWorks生成二维码
在现在的项目中,较多的使用到二维码,前面介绍过一篇使用Gma生成二维码的操作,现在介绍一个第三方组件,主要介绍生成二维码,二维码的解析,以及对二维码的相关信息的选择,现在介绍ThoughtWorks用 ...
- C#运用GmaQrCode生成二维码
项目中需要生成二维码,方法比较多,可以采用JS插件,也可以采用第三方插件后台生成二维码,在后台方法中可以采用QRCode或者GmaQrCode,现在介绍一种C#在后台生成二维码的方法: /// < ...
- Jquery.Qrcode在客户端动态生成二维码并添加自定义Logo
0 Jquery.Qrcode简介 Jquery.Qrcode.js是一个在浏览器端基于Jquery动态生成二维码的插件,支持Canvas和Table两种渲染方式,它的优点是在客户端动态生成,减轻了服 ...
- 使用jquery-qrcode生成二维码
一.使用jquery-qrcode生成二维码 先简单说一下jquery-qrcode,这个开源的三方库(可以从https://github.com/jeromeetienne/jquery-qrcod ...
- JS生成二维码,允许中文转码
一.使用jquery-qrcode生成二维码 先简单说一下jquery-qrcode,这个开源的三方库(可以从https://github.com/jeromeetienne/jquery-qrcod ...
- JavaScript的学习--生成二维码
有一些耗cpu的计算,完全可以在客户端上计算,比如生成二维码. qrcode其实是通过计算,然后使用jquery实现图形渲染和画图.支持canvas和table两种方式生成我们所需的二维码. 具体用法 ...
随机推荐
- Nmap 操作手册 - 完整版
目录 Nmap - 基础篇 Nmap 安装 RedHat Windows Debina & Ubuntu Others Linux Nmap 参数(简单版) 目标说明 主机发现 扫描技术 端口 ...
- 无意苦争春,一任群芳妒!M1 Mac book(Apple Silicon)能否支撑全栈工程师的日常?(Python3/虚拟机/Docker/Redis)
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_187 就像大航海时代里突然诞生的航空母舰一样,苹果把玩着手心里远超时代的M1芯片,微笑着对Intel说:"不好意思,虽然 ...
- Odoo14 一些好用的开源的模块
# odoo14中一些好用的开源的模块 1.intero_reload_form 刷新按钮(页面数据刷新,而不是按F5刷新整个页面) 2.ms_magic_button 弹框下拉选项 3.sessio ...
- boot issue
Q:生产过程中不小心把 boot文件删除了 ,或者升级kenerl时发现版本不兼容,需要回退,此时没有快照备份情况如何操作? A:boot 主要文件是内核和grub引导文件 修复方法: 1.进入救 ...
- linux-0.11分析:init文件 main.c的第一个初始化函数mem_int 第四篇随笔
init文件夹 mian.c 参考 [github这个博主的 厉害][ https://github.com/sunym1993/flash-linux0.11-talk ] 首先先看看这个mian. ...
- C#《原CSharp》第四回 人常见岁月更替 却难知人文相继
纪芾显然此时并不是很能理解纪老爷子口中是也不是这句话的意思,不过他依然将这个要点记在了心里,方便以后悟出其最终门道的时候进行比对. "今天,我在璃月港北边的一户人家,遇到了一个挺有意思的后生 ...
- LuoguP4719 【模板】动态 DP(动态DP,LCT)
\(n \times m\)的算法谁都会吧,注意到每次修改影响的仅是一部分的信息,因此可思考优化. 将每个节点对应一个矩阵\(\begin{bmatrix} g[v][0] & g[v][0] ...
- LuoguP1725 琪露诺 (动态规划)
\(单调队列\) 或 \(堆\) 优化 #include <iostream> #include <cstdio> #include <cstring> #incl ...
- 删除MySQL数据用户
mysql删除用户的方法: 1.使用"drop user 用户名;"命令删除: 2.使用"delete from user where user='用户名' and ho ...
- Excelize 2.3.2 发布,Go 语言 Excel 文档基础库,2021 年首个更新
Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库,基于 ECMA-376,ISO/IEC 29500 国际标准.可以使用它来读取.写入由 Microsoft Exc ...