.net 6使用SkiaSharp生成验证码部署在docker上无法显示
.net6之后,微软默认不支持System.Drawing在linux上的使用,原有的方式在.net 6上需要配置发布生成的*.runtimeconfig.json的configProperties节点下配置如下内容才支持,但在后续版本中删除该开关。
1.依赖的程序集不要直接使用SkiaSharp,而要使用SkiaSharp.NativeAssets.Linux.NoDependencies
2.如上如果docker打包直接用官方的镜像,那可能显示验证码底图可以显示,但无法具体的验证码,字体什么的加上也没用的话,在Dockerfile里还是需要添加libgdiplus的安装引用(虽然微软不推荐用这个,但安装了它确实能显示了,后续版本也可以继续升级)
Dockerfile文件中添加
RUN apt-get update -y && apt-get install -y libgdiplus && apt-get clean && ln -s /usr/lib/libgdiplus.so /usr/lib/gdiplus.dll
附录验证码生成代码
1 public static byte[] GenerateValidateCode(string code, int width, int height, int textSize) 2 { 3 Random random = new(); 4 //验证码颜色集合 5 var colors = new[] { SKColors.Black, SKColors.Red, SKColors.DarkBlue, SKColors.Green, SKColors.Orange, SKColors.Brown, SKColors.DarkCyan, SKColors.Purple }; 6 var backcolors = new[] { SKColors.AntiqueWhite, SKColors.WhiteSmoke, SKColors.FloralWhite }; 7 //验证码字体集合 8 var fonts = new[] {"Cantarell" }; 9 if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) 10 { 11 fonts = new[] { "宋体" }; 12 } 13 //相当于js的 canvas.getContext('2d') 14 using var image2d = new SKBitmap(width, height, SKColorType.Bgra8888, SKAlphaType.Premul); 15 //相当于前端的canvas 16 using var canvas = new SKCanvas(image2d); 17 //填充白色背景 18 canvas.DrawColor(backcolors[random.Next(0, backcolors.Length - 1)]); 19 //样式 跟xaml差不多 20 using var drawStyle = new SKPaint(); 21 //填充验证码到图片 22 for (int i = 0; i < code.Length; i++) 23 { 24 drawStyle.IsAntialias = true; 25 drawStyle.TextSize = textSize; 26 var font = SKTypeface.FromFamilyName(fonts[random.Next(0, fonts.Length - 1)], SKFontStyleWeight.SemiBold, SKFontStyleWidth.ExtraCondensed, SKFontStyleSlant.Upright); 27 drawStyle.Typeface = font; 28 drawStyle.Color = colors[random.Next(0, colors.Length - 1)]; 29 //写字 30 canvas.DrawText(code[i].ToString(), (i + 1) * 16, 28, drawStyle); 31 } 32 //生成6条干扰线 33 for (int i = 0; i < 6; i++) 34 { 35 drawStyle.Color = colors[random.Next(colors.Length)]; 36 drawStyle.StrokeWidth = 1; 37 canvas.DrawLine(random.Next(0, code.Length * 15), random.Next(0, 60), random.Next(0, code.Length * 16), random.Next(0, 30), drawStyle); 38 } 39 //巴拉巴拉的就行了 40 using var img = SKImage.FromBitmap(image2d); 41 using var p = img.Encode(SKEncodedImageFormat.Png, 100); 42 using var ms = new MemoryStream(); 43 //保存到流 44 p.SaveTo(ms); 45 46 byte[] arr = new byte[ms.Length]; 47 ms.Position = 0; 48 ms.Read(arr, 0, (int)ms.Length); 49 return arr; 50 }
效果