经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Docker » 查看文章
关于.Net 6.0 在Linux ,Docker容器中,不安装任何依赖就生成图形验证码!!!!!!!!!!!
来源:cnblogs  作者:<杜子腾  时间:2023/9/25 16:50:30  对本文有异议

在.Net Framework时代,我们生成验证码大多都是用System.Drawing。

在.Net 6中使用也是没有问题的。

但是,System.Drawing却依赖于Windows GDI+。

为了实现跨平台,我陷入了沉思!!

 

微软推荐使用SkiaSharp 进行替代,所以就开始了,踩坑之旅

首先,安装SkiaSharp 

编写好图形生成代码。

  1. using SkiaSharp;
  2. using System.Drawing;
  3. using System.Drawing.Text;
  4. namespace VertifyCode
  5. {
  6. public class VerifyCodeHelper
  7. {
  8. private static readonly char[] Chars = { '0','1','2','3','4','5','6','8','9',
  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' };
  10. //private static readonly int Width = 90;
  11. //private static readonly int Height = 35;
  12. private static string GenCode(int num)
  13. {
  14. var code = string.Empty;
  15. var r = new Random();
  16. for (int i = 0; i < num; i++)
  17. {
  18. code += Chars[r.Next(Chars.Length)].ToString();
  19. }
  20. return code;
  21. }
  22. /// <summary>
  23. /// 获取图像数字验证码
  24. /// </summary>
  25. /// <returns></returns>
  26. public static (string code, byte[] bytes) GetVerifyCode()
  27. {
  28. var code = GenCode(4);
  29. int width = 128;
  30. int height = 45;
  31. Random random = new();
  32. //创建bitmap位图
  33. using SKBitmap image = new(width, height, SKColorType.Bgra8888, SKAlphaType.Premul);
  34. //创建画笔
  35. using SKCanvas canvas = new(image);
  36. //填充背景颜色为白色
  37. canvas.DrawColor(SKColors.White);
  38. //画图片的背景噪音线
  39. for (int i = 0; i < (width * height * 0.015); i++)
  40. {
  41. using SKPaint drawStyle = new();
  42. drawStyle.Color = new(Convert.ToUInt32(random.Next(Int32.MaxValue)));
  43. canvas.DrawLine(random.Next(0, width), random.Next(0, height), random.Next(0, width), random.Next(0, height), drawStyle);
  44. }//将文字写到画布上
  45. using (SKPaint drawStyle = new())
  46. {
  47. drawStyle.Color = SKColors.Red;
  48. drawStyle.TextSize = height;
  49. drawStyle.StrokeWidth = 1;
  50. float emHeight = height - (float)height * (float)0.14;
  51. float emWidth = ((float)width / code.Length) - ((float)width * (float)0.13);
  52. canvas.DrawText(code, emWidth, emHeight, drawStyle);
  53. }
  54. //画图片的前景噪音点
  55. for (int i = 0; i < (width * height * 0.15); i++)
  56. {
  57. image.SetPixel(random.Next(0, width), random.Next(0, height), new SKColor(Convert.ToUInt32(random.Next(Int32.MaxValue))));
  58. }
  59. using var img = SKImage.FromBitmap(image);
  60. using SKData p = img.Encode(SKEncodedImageFormat.Png, 100);
  61. return (code, p.ToArray());
  62. }
  63. }
  64. }

 

在自身Windows机器上运行,哈哈,完美

 接下来,我就开始部署到Linux

部署完成后,查看日志。靠!!!!

因为咱们公司项目是部署到客户环境,客户环境同样也是内网,如果安装依赖,会非常麻烦,而且每一个客户都需要安装。所以我的目的是在不安装任何依赖的情况下,在Linux上生成图形验证码

 居然用不了,不是跨平台嘛。

于是乎,百度查询,找到了这个nuget包

SkiaSharp.NativeAssets.Linux.NoDependencies

 

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

安装,部署,然后就出现以下情况

 好家伙,字内,图有,没有字啊

 

 在我查阅资料以后,发现Linux上没有字体文件,然后我就开始怀疑人生。

因为是Docker环境,再加上没有外网,所以安装字体是个大麻烦。

但我们可以换一种思路,我提供一个字体文件,能不能让程序指定去读取这个文件

带着这个思路,我开始翻阅SkiaSharp的源码,并发现了这个类

 

字体管理类,说明是可以手动注入字体的。

然后找到了以下方法

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

 

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

最终代码

  1. //因为Linux不会有字体文件,所以读取项目中的字体文件,以便生成验证码字体
  2. SKFont font = new SKFont(SKFontManager.Default.CreateTypeface(File.Open("msyh.ttc", FileMode.Open)));
  3. font.Size = 38;
  4. //将文字写到画布上
  5. using (SKPaint drawStyle = new())
  6. {
  7. drawStyle.Color = SKColors.Red;
  8. drawStyle.TextSize = height;
  9. drawStyle.StrokeWidth = 1;
  10.  
  11. float emHeight = height - (float)height * (float)0.14;
  12. float emWidth = ((float)width / code.Length) - ((float)width * (float)0.13);
  13. canvas.DrawText(code, emWidth, emHeight, font, drawStyle);
  14. }

  

 字体文件从哪取,可以在C:/Windows/Fonts这个路径下复制出来,是可以兼容Linux的

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

 

 

 

OK搞定!完结撒花

 

原文链接:https://www.cnblogs.com/Thayou/p/17717102.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号