驗證碼這個功能是十分常見的,各大系統的登陸頁面都會有。今天介紹一下最爲普通的驗證碼。前端
不管最終給到前端的是圖片格式的驗證碼仍是base64格式的驗證碼,其實都離不開這樣的一步操做,都要先在後臺生成一個圖片。git
就我的經驗來講,早期的.NET Core想在Linux/Docker下面搞圖片這些仍是相對麻煩一些的,首先是組件這一塊,其次是依賴這一塊。github
不過,如今方便多了。docker
下面就基於ImageSharp
這個組件來實踐一下。app
<ItemGroup> <PackageReference Include="SixLabors.ImageSharp" Version="1.0.0-beta0007" /> <PackageReference Include="SixLabors.Fonts" Version="1.0.0-beta0009" /> <PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta0007" /> </ItemGroup>
須要注意的是,ImageSharp目前還不是正式版。dom
示例用的是comic.ttf
,這個只有240kb,算是比較小的了。字體
這裏選一個小一點的字體是由於不想讓打包好的鏡像太大,若是各位大佬有更小體積的字體能夠告訴我一下哈。ui
首先是生成隨機數,應該不用說太多,若是先生成完成不同的數字或字母,自由控制就好。編碼
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; }
而後就是生成的核心代碼了。.net
private static readonly Color[] Colors = { Color.Black, Color.Red, ... }; private static readonly char[] Chars = { '0', .... }; private static readonly int Width = 90; private static readonly int Height = 35; public static (string code, byte[] bytes) GenVCode(int num) { var code = GenCode(num); var r = new Random(); using var image = new Image<Rgba32>(Width, Height); // 字體 var font = SystemFonts.CreateFont(SystemFonts.Families.First().Name, 25, FontStyle.Bold); image.Mutate(ctx => { // 白底背景 ctx.Fill(Color.White); // 畫驗證碼 for (int i = 0; i < code.Length; i++) { ctx.DrawText(code[i].ToString() , font , Colors[r.Next(Colors.Length)] , new PointF(20 * i + 10, r.Next(2, 12))); } // 畫干擾線 for (int i = 0; i < 10; i++) { var pen = new Pen(Colors[r.Next(Colors.Length)], 1); var p1 = new PointF(r.Next(Width), r.Next(Height)); var p2 = new PointF(r.Next(Width), r.Next(Height)); ctx.DrawLines(pen, p1, p2); } // 畫噪點 for (int i = 0; i < 80; i++) { var pen = new Pen(Colors[r.Next(Colors.Length)], 1); var p1 = new PointF(r.Next(Width), r.Next(Height)); var p2 = new PointF(p1.X + 1f, p1.Y + 1f); ctx.DrawLines(pen, p1, p2); } }); using var ms = new System.IO.MemoryStream(); // gif 格式 image.SaveAsGif(ms); return (code, ms.ToArray()); }
都是中規中矩的代碼,這裏須要注意下面幾個地方:
最後就是調用了。
[HttpGet] public IActionResult GetCode() { var (code, bytes) = VCodeHelper.GenVCode(4); // code handle logic System.Console.WriteLine(code); return File(bytes, "image/gif"); }
簡單修改一下Dockerfile,加一句複製字體的命令。
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base WORKDIR /app EXPOSE 80 # 複製字體到 /usr/share/fonts 目錄 COPY ./comic.ttf /usr/share/fonts/comic.ttf FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build WORKDIR /src COPY . . RUN dotnet restore "VCodeTest.sln" WORKDIR /src/VCodeTest RUN dotnet build "VCodeTest.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "VCodeTest.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "VCodeTest.dll"]
生成鏡像,運行效果以下:
文中的示例代碼能夠在個人github找到:
https://github.com/catcherwong-archive/2020/tree/master/05/VCodeTest
ImageSharp 這個組件用起來仍是挺舒服的,你們能夠嘗試嘗試。