網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
.NET?SkiaSharp?生成二維碼驗(yàn)證碼及指定區(qū)域截取方法實(shí)現(xiàn)_實(shí)用技巧
作者:張曉棟 ? 更新時(shí)間: 2022-11-23 編程語(yǔ)言正文
在最新版的 .NET 平臺(tái)中,微軟在逐步放棄 System.Drawing.Imaging ,給出的理由如下:
System.Drawing命名空間對(duì)某些操作系統(tǒng)和應(yīng)用程序類(lèi)型有一些限制。
在Windows, System.Drawing 依賴(lài)于GDI+操作系統(tǒng)附帶的本機(jī)庫(kù)。 某些Windows SKUS Windows Server Core 或 Windows Nano)不包含此本機(jī)庫(kù)作為 OS 的一部分。 如果使用此命名空間并且無(wú)法加載庫(kù),則運(yùn)行時(shí)將引發(fā)異常。
命名空間中的某些類(lèi)型依賴(lài)于 GDI+ ,而 Windows 服務(wù)以及 ASP.NET Core 和 System.Drawing ASP.NET 應(yīng)用不支持。 這些類(lèi)型在System.Drawing.Common NuGet包中,并包括 System.Drawing.Bitmap 和 System.Drawing.Font 。 但是,命名空間中的基元類(lèi)型(如 System.Drawing.Color 、、 和 System.Drawing.Size System.Drawing.Point System.Drawing.Rectangle )可以在任何應(yīng)用程序中使用。
在 .NET 5 和早期版本中,System.Drawing.Common NuGet 包適用于 Windows、Linux 和 macOS。 但是,存在一些平臺(tái)差異。 在 Linux 和 macOS 上,GDI+功能由libgdiplus) 庫(kù)實(shí)現(xiàn)。 默認(rèn)情況下,大多數(shù) Linux 發(fā)行版中不會(huì)安裝此庫(kù),也不支持 GDI+ 和 macOS 上Windows的所有功能。 還有一些平臺(tái),其中 libgdiplus 完全不可用。 若要在 Linux 和 macOS 上使用 System.Drawing.Common 包中的類(lèi)型,必須單獨(dú)安裝 libgdiplus。 有關(guān)詳細(xì)信息,請(qǐng)參閱在Linux 上安裝 .NET或在macOS 上安裝 .NET。
在 .NET 6 及更高版本中,System.Drawing.Common NuGet 包僅在 Windows操作系統(tǒng)上受支持。 有關(guān)詳細(xì)信息,請(qǐng)參閱 僅支持System.Drawing.Common Windows。
所以我將項(xiàng)目中原先使用 System.Drawing.Imaging 實(shí)現(xiàn)的方法采用 SkiaSharp 進(jìn)行了重寫(xiě)。
SkiaSharp是 Google 的Skia 圖形庫(kù)的 .NET 包裝器,可用于跨移動(dòng)、服務(wù)器和桌面平臺(tái)繪制 2D 圖形。SkiaSharp 可與 OpenGL 一起用于硬件加速渲染。SkiaSharp 最初由 Mono 開(kāi)發(fā),但現(xiàn)在由 Microsoft 維護(hù),并根據(jù)MIT License提供。
依賴(lài)的 Nuget 組件如下
- SkiaSharp
- SkiaSharp.NativeAssets.Linux
- SkiaSharp.QrCode
using SkiaSharp.QrCode;
namespace Common
{
public class ImgHelper
{
/// <summary>
/// 生成二維碼
/// </summary>
/// <param name="text">二維碼內(nèi)容</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>
/// 從圖片截取部分區(qū)域
/// </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>
/// 獲取圖像數(shù)字驗(yàn)證碼
/// </summary>
/// <param name="text">驗(yàn)證碼內(nèi)容,如4為數(shù)字</param>
/// <returns></returns>
public static byte[] GetVerifyCode(string text)
{
int width = 128;
int height = 45;
Random random = new();
//創(chuàng)建bitmap位圖
using SKBitmap image = new(width, height, SKColorType.Bgra8888, SKAlphaType.Premul);
//創(chuàng)建畫(huà)筆
using SKCanvas canvas = new(image);
//填充背景顏色為白色
canvas.DrawColor(SKColors.White);
//畫(huà)圖片的背景噪音線
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);
}
//將文字寫(xiě)到畫(huà)布上
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);
}
//畫(huà)圖片的前景噪音點(diǎn)
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();
}
}
}
項(xiàng)目如果是在 windows 服務(wù)器下運(yùn)行則不需要任何安裝任何依賴(lài)項(xiàng),如果是在 linux 服務(wù)下運(yùn)行則需要安裝 libfontconfig1,如 ubuntu 的安裝命令
apt-get update
apt-get -y install libfontconfig1
如果是采用 docker 模式運(yùn)行,則需要在 dockerfile 中添加如下配置,該命令適用于 debian 和 ubuntu 的 docker
RUN apt-get update && apt-get -y install libfontconfig1
至此 .NET 采用 SkiaSharp 生成二維碼和圖形驗(yàn)證碼及圖片進(jìn)行指定區(qū)域截取方法實(shí)現(xiàn) 就講解完了,有任何不明白的,可以在文章下面評(píng)論或者私信我,歡迎大家積極的討論交流,有興趣的朋友可以關(guān)注我目前在維護(hù)的一個(gè) .NET 基礎(chǔ)框架項(xiàng)目,項(xiàng)目地址如下
https://github.com/berkerdong/NetEngine
https://gitee.com/berkerdong/NetEngine
原文鏈接:https://www.cnblogs.com/berkerdong/p/16779385.html
相關(guān)推薦
- 2022-08-25 C++超詳細(xì)梳理IO流操作_C 語(yǔ)言
- 2022-04-20 C語(yǔ)言特殊符號(hào)的補(bǔ)充理解_C 語(yǔ)言
- 2023-07-25 SpringBoot整合Mybatis詳解
- 2023-01-27 Python基礎(chǔ)教程之while循環(huán)用法講解_python
- 2022-06-11 python中Event實(shí)現(xiàn)線程間同步介紹_python
- 2022-09-20 C#單線程和多線程端口掃描器詳解_C#教程
- 2022-06-12 Python使用matplotlib.pyplot?as?plt繪圖圖層優(yōu)先級(jí)問(wèn)題_python
- 2022-05-05 Python&Matlab實(shí)現(xiàn)螞蟻群算法求解最短路徑問(wèn)題的示例_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支