首页 > 系统相关 >关于.Net 6.0 在Linux ,Docker容器中,不安装任何依赖就生成图形验证码!!!!!!!!!!!

关于.Net 6.0 在Linux ,Docker容器中,不安装任何依赖就生成图形验证码!!!!!!!!!!!

时间:2023-09-20 13:45:00浏览次数:37  
标签:code drawStyle 6.0 float height width Linux using Net

在.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搞定!完结撒花

 

标签:code,drawStyle,6.0,float,height,width,Linux,using,Net
From: https://www.cnblogs.com/Thayou/p/17717102.html

相关文章

  • 每个.NET开发都应掌握的C#异常处理知识点
    上篇文章讲述了C#集合知识点,本文将介绍C#异常处理知识点。异常处理是.NET开发中至关重要的一部分,它允许开发者在程序出现错误或不正常情况时采取适当的措施,从而提高应用程序的稳定性和可靠性。本文将介绍C#异常处理知识点,异常的基本概念略过,请查看官网。1、自定义异常开发者可以......
  • linux查看文件夹大小、文件数量的方法
    查看文件数量及大小ls-l|grep"^-"|wc-l或find./company-typef|wc-l查看某文件夹下文件的数量,包括子文件夹里的。ls-lR|grep"^-"|wc-l查看某文件夹下文件夹的数量,包括子文件夹里的。ls-lR|grep"^d"|wc-l以上的命令解释:ls-l长列表输出该目录下文件信息(注意这里......
  • linux 中实现部分取反
     001、测试文件(实现仅提取==1185==和其他不包含==数字==的行)[root@pc1test2]#lsa.txt[root@pc1test2]#cata.txt##测试文件==1185==abcadoiafa==1120==asvgaojfajsdfja==3875==yuerdded==1130==afsdalj==1185== 002、sed实现[root@pc1test2]#ls......
  • Linux 动态库符号冲突
    问题起源在Linux下编译动态库的时候,所有的符号默认都是导出的,也就是动态库中的函数名,类名等,在外部都是可见的。当程序引用多个动态库时,由于各个动态库可能属于不同的团队来开发,不同团队使用相同的第三方库的可能性也是有的(例如openssl,libcurl,cjson等),不同的团队使用的第三方......
  • linux关闭终端,后台程序不退出
    你要退出终端会话时,要是存在被停止的进程,会出现警告信息。但如果使用了后台进程,只有某些终端仿真器会在你退出终端会话前提醒你还有后台作业在运行。 如果希望运行在后台模式的脚本在登出控制台后能够继续运行,我再一篇文章中看到,有方法可以实现。有时你会想在终端......
  • asp.Net Core 改变响应值的几种方法
    1.中间件usingMicrosoft.AspNetCore.Mvc;usingSystem.Text;varbuilder=WebApplication.CreateBuilder(args);builder.Services.AddControllers();varapp=builder.Build();app.UseMiddleware<ReplaceMiddleware>();app.MapControllers();app.Run();public......
  • 在 Net7.0环境下通过反射创建对象和调用方法
    一、介绍最近没事干,就用闲暇时间写点东西,也记录一下温习历程。老人说的好,好记性,不如烂笔头。时间一长,当时记忆的再清楚,都会变得模糊,索性就写博客记录下来,如果下次需要,直接打开博客就找到了,不用去网上乱找了。今天我要写一些有关反射创建类型实例和调用方法的文章,......
  • 20230919 .NET面经
    SQLIQuerable和IEnumerable的主要区别?https://stackoverflow.com/questions/252785/what-is-the-difference-between-iqueryablet-and-ienumerabletSothedifferencebetweenIQueryableandIEnumerableisaboutwherethefilterlogicisexecuted.Oneexecuteso......
  • (笔记)Linux修改、查看日期和时间的方法
      1、查看时间、日期#dateFriJan1114:04:10CST2019 2、修改时间语法:date-s"时:分:秒"#date-s"17:20:30" 3、修改日期、时间语法:date-s"年-月-日时:分:秒"#date-s"2019-01-1114:21:30"注意:设置时间需要使用双引号括起来,否则会报错。 ......
  • Linux 下安装安装rz/sz命令
    http://www.ohse.de/uwe/releases/lrzsz-0.12.20.tar.gz  下载lrzsz安装包tarzxvflrzsz-0.12.20.tar.gz&&cdlrzsz-0.12.20#解压并切换到lrzsz-0.12.20目录下面yum -yinstall gcc cc./configuremakemakeinstall上面安装过程默认把lsz和lrz安装到了/usr/loc......