关于.Net 6.0 在Linux ,Docker容器中,不安装任何依赖就生成图形验证码!!!!!!!!!!!
在.Net Framework时代,我们生成验证码大多都是用System.Drawing。
在.Net 6中使用也是没有问题的。
但是,System.Drawing却依赖于Windows GDI+。
为了实现跨平台,我陷入了沉思!!

微软推荐使用SkiaSharp 进行替代,所以就开始了,踩坑之旅
首先,安装SkiaSharp
编写好图形生成代码。
using SkiaSharp;
using System.Drawing;
using System.Drawing.Text; namespace VertifyCode
{
public class VerifyCodeHelper
{
private static readonly char[] Chars = { '0','1','2','3','4','5','6','8','9',
'A','B','C','D','E','F','G','H','I','J','K', 'L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z' };
//private static readonly int Width = 90;
//private static readonly int Height = 35; private static string GenCode(int num)
{
var code = string.Empty;
var r = new Random(); for (int i = 0; i < num; i++)
{
code += Chars[r.Next(Chars.Length)].ToString();
} return code;
}
/// <summary>
/// 获取图像数字验证码
/// </summary>
/// <returns></returns>
public static (string code, byte[] bytes) GetVerifyCode()
{
var code = GenCode(4);
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 / code.Length) - ((float)width * (float)0.13);
canvas.DrawText(code, emWidth, emHeight, drawStyle);
} //画图片的前景噪音点
for (int i = 0; i < (width * height * 0.15); 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 (code, p.ToArray());
}
}
}
在自身Windows机器上运行,哈哈,完美

接下来,我就开始部署到Linux
部署完成后,查看日志。靠!!!!
因为咱们公司项目是部署到客户环境,客户环境同样也是内网,如果安装依赖,会非常麻烦,而且每一个客户都需要安装。所以我的目的是在不安装任何依赖的情况下,在Linux上生成图形验证码
居然用不了,不是跨平台嘛。
于是乎,百度查询,找到了这个nuget包
SkiaSharp.NativeAssets.Linux.NoDependencies

原来,绘图需要很多依赖,但不是每一个Linux都会有这些,由于我们的服务器是内网,不能够在线安装,所有就使用此nuget包。避免缺少依赖。
安装,部署,然后就出现以下情况

好家伙,字内,图有,没有字啊
在我查阅资料以后,发现Linux上没有字体文件,然后我就开始怀疑人生。
因为是Docker环境,再加上没有外网,所以安装字体是个大麻烦。
但我们可以换一种思路,我提供一个字体文件,能不能让程序指定去读取这个文件
带着这个思路,我开始翻阅SkiaSharp的源码,并发现了这个类

字体管理类,说明是可以手动注入字体的。
然后找到了以下方法

看来可以试试,将字体文件,读取成流,注入到程序中

然后再写入文字时,使用该字体示例

最终代码
//因为Linux不会有字体文件,所以读取项目中的字体文件,以便生成验证码字体
SKFont font = new SKFont(SKFontManager.Default.CreateTypeface(File.Open("msyh.ttc", FileMode.Open)));
font.Size = 38;
//将文字写到画布上
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 / code.Length) - ((float)width * (float)0.13);
canvas.DrawText(code, emWidth, emHeight, font, drawStyle);
}
字体文件从哪取,可以在C:/Windows/Fonts这个路径下复制出来,是可以兼容Linux的


接下来就是激动心,颤抖的手,我们部署到Linux(docker)下,试试。

OK搞定!完结撒花
关于.Net 6.0 在Linux ,Docker容器中,不安装任何依赖就生成图形验证码!!!!!!!!!!!的更多相关文章
- 如何在 Docker 容器中运行 Kali Linux 2.0
https://linux.cn/article-6103-1.html Kali Linux 是一个对于安全测试人员和白帽的一个知名操作系统.它带有大量安全相关的程序,这让它很容易用于渗透测试.最近 ...
- Linux下将.Asp Core 部署到 Docker容器中
我们来部署一个简单的例子: 将一个简单的.Aps Core项目部署到Docker容器中并被外网访问 说明: 下面的步骤都是建立在宿主服务器系统已经安装配置过Docker容器,安装Docker相对比较简 ...
- 在docker容器中编译hadoop 3.1.0
在docker容器中编译hadoop 3.1.0 优点:docker安装好之后可以一键部署编译环境,不用担心各种库不兼容等问题,编译失败率低. Hadoop 3.1.0 的源代码目录下有一个 `sta ...
- 在docker容器中安装和使用,linux版的powershell
powershell 传教士 原创文章.始于 2016-09-18 ,2016-10-27修改powershell docker官网.允许转载,但必须保留名字和出处,否则追究法律责任 1 在任意版本的 ...
- .Net Core 自动化部署:使用jenkins部署到linux docker容器运行
上次我们说到.Net Core 自动化部署:使用docker版jenkins部署dotnetcore应用,这次我们使用jenkins发布我们的.NET Core站点到docker容器中运行,为后面的的 ...
- .Net Core 3.0 的 docker 容器中运行 无法 访问 Oracle数据库
.Net Core 3.0 的 docker 容器中运行 无法 访问 Oracle数据库 , 一直报下面的错误 ORA-00604: error occurred at recursive SQL ...
- 复制docker容器中的nginx某个文件到linux中
前提:docker容器中的nginx要开启
- Docker容器中运行ASP.NET Core
在Linux和Windows的Docker容器中运行ASP.NET Core 译者序:其实过去这周我都在研究这方面的内容,结果周末有事没有来得及总结为文章,Scott Hanselman就捷足先登了. ...
- 在 docker 容器中捕获信号
我们可能都使用过 docker stop 命令来停止正在运行的容器,有时可能会使用 docker kill 命令强行关闭容器或者把某个信号传递给容器中的进程.这些操作的本质都是通过从主机向容器发送信号 ...
- Docker容器中开始.NETCore之路
一.引言 开始写这篇博客前,已经尝试练习过好多次Docker环境安装,.Net Core环境安装了,在这里替腾讯云做一个推广,假如我们想学习.练手.net core 或是Docker却苦于没有开发环境 ...
随机推荐
- 20200825 BAT批处理文件详细教程
原文链接:https://www.jb51.net/article/151923.htm 纯转载.侵删. 第一章 批处理基础 第一节 常用批处理内部命令简介 批处理定义:顾名思义,批处理文件是将一系列 ...
- 【HarmonyOS】如何获取公共目录的图片等文件(API7 FA模型JS语言)
[关键字] API7.JS.公共目录.@ohos.multimedia.mediaLibrary [前言] 在使用API7 JS开发HarmonyOS应用时,需要获取非应用目录即内部存储公共目录下 ...
- GPU技术在大规模计算和并行计算中的应用和挑战
目录 1. 引言 2. 技术原理及概念 3. 实现步骤与流程 4. 应用示例与代码实现讲解 5. 优化与改进 GPU 技术在大规模计算和并行计算中的应用和挑战 随着计算机硬件的不断发展和计算能力的提高 ...
- 如何将mp4文件解复用并且解码为单独的.yuv图像序列以及.pcm音频采样数据?
一.初始化解复用器 在音视频的解复用的过程中,有一个非常重要的结构体AVFormatContext,即输入文件的上下文句柄结构,代表当前打开的输入文件或流.我们可以将输入文件的路径以及AVFormat ...
- rocketmq-console基本使用
rocketmq-console基本使用 作用:rocketmq-console是rocketmq的一款可视化工具,提供了mq的使用详情等功能. 一.安装部署 下载rocketmq组件 rocketm ...
- 解决php中通过exec调用python脚本报ModuleNotFoundError错误
背景 出于某些原因,我们有时会在PHP中通过exec来调用Python代码,有可能是某些功能只能用Python实现(或用Python实现比较方便),有可能是出于性能考虑(Python可以执行耗时任务) ...
- std::ofstream 写本地音频
最近线上 PK 偶然出现双方主播互相听不见声音的情况,在日志不能明确体现问题时,就需要抓下主播本地的音频和远端的音频来确定数据是在哪消失的 所以我们用到一个比较简单的流写出的标准库类:std::ofs ...
- 2021-11-17 WPF初识
StackPanel容器:默认竖直排列,Orientation="Horizontal"横向排列,超过就不会显示 wrapPanel:超过会自动换行 设置样式: <Windo ...
- 数据分析师如何用SQL解决业务问题?
本文来自问答. 提问:数据分析人员需要掌握sql到什么程度? 请问做一名数据分析人员,在sql方面需要掌握到什么程度呢?会增删改查就可以了吗?还是说关于开发的内容也要会?不同阶段会有不同的要求吗? 正 ...
- TCP四次挥手会经历这么多状态
TCP三次握手 中讲述了序列号和建立连接,这一篇来说说释放连接. 标志位 TCP首部中在属性标志位,和建立连接.释放连接有关,位于保留和窗口字段中间,其中三个标识与断开连接有关. ACK: ackno ...