C# 使用 SkiaSharp 實現驗證碼
代碼
/// <summary>
/// 驗證碼 SkiaSharp 庫(不用考慮太多跨平台問題)
///
/// <para>添加包(選擇對應平台安裝)</para>
/// <para>dotnet add package SkiaSharp</para>
/// <para>dotnet add package SkiaSharp.NativeAssets.Linux</para>
/// <para>dotnet add package SkiaSharp.NativeAssets.macOS</para>
/// <para>dotnet add package SkiaSharp.NativeAssets.Win32</para>
/// </summary>
public class CaptchaCodeSK
{
/// <summary>
/// Tuple 的第一個值是表達式
/// Tuple 的第二個值是表達式結果
/// </summary>
/// <returns></returns>
public static Tuple<string, int> GetCaptchaCode()
{
var random = new Random();
//數據
var value = 0;
var first = random.Next(10, 100);//10-99
var second = random.Next(10, 100);//10-99
//計算方式
var operators = new char[] { '+', '-', '×', '÷' };
var operatorChar = operators[random.Next(0, 2 /** operators.Length **/)];
switch (operatorChar)
{
case '+':
value = first + second;
break;
case '-':
// 第1個數要大於第二個數
if (first < second)
{
var temp = first;
first = second;
second = temp;
}
value = first - second;
break;
case '×':
value = first * second;
break;
case '÷':
//被除數不能為零
if (second == 0)
{
second = 1;
}
value = first / second;
break;
}
//公式
var randomCode = string.Format("{0}{1}{2}=?", first, operatorChar, second);
//結果
return new Tuple<string, int>(randomCode, value);
}
/// <summary>
/// 生成驗證碼圖片
/// </summary>
/// <param name="randomCode"></param>
/// <returns></returns>
public static byte[] CreateCaptchaImage(string randomCode)
{
var random = new Random();
//驗證碼顏色集合
var colors = new[] { SKColors.Black, SKColors.Red, SKColors.DarkBlue, SKColors.Green, SKColors.Orange, SKColors.Brown, SKColors.DarkCyan, SKColors.Purple };
//驗證碼字體集合
var fonts = new[] { "Verdana", "Microsoft Sans Serif", "Comic Sans MS", "Arial", "宋體" };
//相當於js的 canvas.getContext('2d')
using var image2d = new SKBitmap(100, 30, SKColorType.Bgra8888, SKAlphaType.Premul);
//相當於前端的canvas
using var canvas = new SKCanvas(image2d);
//填充白色背景
canvas.DrawColor(SKColors.AntiqueWhite);
//樣式 跟xaml差不多
using var drawStyle = new SKPaint();
//生成幹擾點
for (int i = 0; i < 50; i++)
{
drawStyle.Color = colors[random.Next(colors.Length)];
drawStyle.StrokeWidth = 1;
var x1 = random.Next(0, randomCode.Length * 15);
var y1 = random.Next(0, 60);
var x2 = x1 + 1;
var y2 = y1;
canvas.DrawLine(x1, y1, x2, y2, drawStyle);
}
//填充驗證碼到圖片
for (int i = 0; i < randomCode.Length; i++)
{
var fontData = randomCode[i].ToString();
var fontSize = random.Next(26, 31);
var fontType = fonts[random.Next(0, fonts.Length - 1)];
//樣式
drawStyle.IsAntialias = true;
drawStyle.TextSize = fontSize;
drawStyle.Typeface = SKTypeface.FromFamilyName(fontType, SKFontStyleWeight.SemiBold, SKFontStyleWidth.ExtraCondensed, SKFontStyleSlant.Upright);
drawStyle.Color = colors[random.Next(0, colors.Length - 1)];
//寫字
var x1 = i * 14;
var y1 = 28;
canvas.DrawText(fontData, x1, y1, drawStyle);
}
//生成幹擾線
for (int i = 0; i < 5; i++)
{
drawStyle.Color = colors[random.Next(colors.Length)];
drawStyle.StrokeWidth = 1;
var x1 = random.Next(0, randomCode.Length * 15);
var y1 = random.Next(0, 60);
var x2 = random.Next(0, randomCode.Length * 16);
var y2 = random.Next(0, 30);
canvas.DrawLine(x1, y1, x2, y2, drawStyle);
}
//創建對象信息
using var img = SKImage.FromBitmap(image2d);
using var p = img.Encode(SKEncodedImageFormat.Png, 100);
using var ms = new MemoryStream();
//保存到流
p.SaveTo(ms);
var bytes = ms.GetBuffer();
return bytes;
}
/// <summary>
/// Tuple 的第一個值是表達式結果
/// Tuple 的第二個值是表達式圖片
/// </summary>
/// <returns></returns>
public static Tuple<string, byte[]> GetImgData()
{
var tuple = GetCaptchaCode();
var code = tuple.Item2.ToString();
var img = CreateCaptchaImage(tuple.Item1);
return new Tuple<string, byte[]>(code, img);
}
}使用方法
var tuple = CaptchaCodeSK.GetImgData();
SessionHelper.Set("ValidateCode", tuple.Item1);
return File(tuple.Item2, "image/jpg");版權屬於:zgcwkj
本文鏈接:https://www.zgcwkj.com/archives/200.html
轉載聲明:請注明本文章的標題及內容的出處和聲明,謝謝
評論已關閉