Skip to content

Commit 67a4d5f

Browse files
author
283591387@qq.com
committed
增加跨平台验证码SkiaSharp(by @3ddbz)
1 parent 7b8dbf6 commit 67a4d5f

File tree

12 files changed

+338
-245
lines changed

12 files changed

+338
-245
lines changed
Lines changed: 80 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,98 @@
1-
using System;
1+
using SkiaSharp;
2+
using System;
23
using System.IO;
34
using System.Linq;
4-
using SkiaSharp;
55

6-
namespace VOL.Core.Utilities;
6+
namespace VOL.Core.Utilities
7+
{
8+
public static class VierificationCodeHelpers
9+
{ //验证码字体集合
10+
private static readonly string[] fonts = { "Verdana", "Microsoft Sans Serif", "Comic Sans MS", "Arial", "宋体" };
11+
private static readonly SKColor[] colors = { SKColors.Black, SKColors.Green, SKColors.Brown };
712

8-
public static class VierificationCodeHelpers
9-
{ //验证码字体集合
10-
private static readonly string[] fonts = { "Verdana", "Microsoft Sans Serif", "Comic Sans MS", "Arial", "宋体" };
11-
private static readonly SKColor[] colors = { SKColors.Black, SKColors.Red, SKColors.DarkBlue, SKColors.Green,
12-
SKColors.Orange, SKColors.Brown, SKColors.DarkCyan, SKColors.Purple};
13-
14-
/// <summary>
15-
///
16-
/// </summary>
17-
/// <param name="code"></param>
18-
/// <returns></returns>
19-
public static string CreateBase64Image(string code)
20-
{
21-
var random = new Random();
22-
var info = new SKImageInfo((int)code.Length * 18, 32);
23-
using var bitmap = new SKBitmap(info);
24-
using var canvas = new SKCanvas(bitmap);
13+
/// <summary>
14+
///
15+
/// </summary>
16+
/// <param name="code"></param>
17+
/// <returns></returns>
18+
public static string CreateBase64Image(string code)
19+
{
20+
var random = new Random();
21+
var info = new SKImageInfo((int)code.Length * 18, 32);
22+
using var bitmap = new SKBitmap(info);
23+
using var canvas = new SKCanvas(bitmap);
2524

26-
canvas.Clear(SKColors.White);
25+
canvas.Clear(SKColors.White);
2726

28-
using var pen = new SKPaint();
29-
pen.FakeBoldText = true;
30-
pen.Style = SKPaintStyle.Stroke;
31-
pen.TextSize = 0.9f * info.Width * pen.TextSize / pen.MeasureText(code);
27+
using var pen = new SKPaint();
28+
pen.FakeBoldText = true;
29+
pen.Style = SKPaintStyle.Fill;
30+
pen.TextSize = 20;// 0.6f * info.Width * pen.TextSize / pen.MeasureText(code);
3231

33-
//绘制随机字符
34-
for (int i = 0; i < code.Length; i++)
35-
{
36-
pen.Color = random.GetRandom(colors);//随机颜色索引值
37-
pen.Typeface = SKTypeface.FromFamilyName(random.GetRandom(fonts), 700, 20, SKFontStyleSlant.Italic);//配置字体
38-
var point = new SKPoint()
32+
//绘制随机字符
33+
for (int i = 0; i < code.Length; i++)
3934
{
40-
X = i * 12,
41-
Y = info.Height - ((i + 1) % 2 == 0 ? 2 : 4)
42-
};
43-
canvas.DrawText(code.Substring(i, 1), point, pen);//绘制一个验证字符
44-
}
35+
pen.Color = random.GetRandom(colors);//随机颜色索引值
36+
pen.Typeface = SKTypeface.FromFamilyName(random.GetRandom(fonts), 700, 20, SKFontStyleSlant.Italic);//配置字体
37+
var point = new SKPoint()
38+
{
39+
X = i * 16,
40+
Y = 22// info.Height - ((i + 1) % 2 == 0 ? 2 : 4),
4541

46-
//绘制噪点
47-
var points = Enumerable.Range(0, 100).Select(
48-
_ => new SKPoint(random.Next(bitmap.Width), random.Next(bitmap.Height))
49-
).ToArray();
50-
canvas.DrawPoints(
51-
SKPointMode.Points,
52-
points,
53-
pen);
42+
};
43+
canvas.DrawText(code.Substring(i, 1), point, pen);//绘制一个验证字符
44+
}
5445

55-
//绘制贝塞尔线条
56-
for (int i = 0; i < 2; i++)
57-
{
58-
var p1 = new SKPoint(0, random.Next(bitmap.Height));
59-
var p2 = new SKPoint(random.Next(bitmap.Width), random.Next(bitmap.Height));
60-
var p3 = new SKPoint(random.Next(bitmap.Width), random.Next(bitmap.Height));
61-
var p4 = new SKPoint(bitmap.Width, random.Next(bitmap.Height));
46+
//绘制噪点
47+
var points = Enumerable.Range(0, 100).Select(
48+
_ => new SKPoint(random.Next(bitmap.Width), random.Next(bitmap.Height))
49+
).ToArray();
50+
canvas.DrawPoints(
51+
SKPointMode.Points,
52+
points,
53+
pen);
54+
55+
//绘制贝塞尔线条
56+
for (int i = 0; i < 2; i++)
57+
{
58+
var p1 = new SKPoint(0, 0);
59+
var p2 = new SKPoint(0, 0);
60+
var p3 = new SKPoint(0, 0);
61+
var p4 = new SKPoint(0, 0);
6262

63-
var touchPoints = new SKPoint[] { p1, p2, p3, p4 };
63+
var touchPoints = new SKPoint[] { p1, p2, p3, p4 };
6464

65-
using var bPen = new SKPaint();
66-
bPen.Color = random.GetRandom(colors);
67-
bPen.Style = SKPaintStyle.Stroke;
65+
using var bPen = new SKPaint();
66+
bPen.Color = random.GetRandom(colors);
67+
bPen.Style = SKPaintStyle.Stroke;
6868

69-
using var path = new SKPath();
70-
path.MoveTo(touchPoints[0]);
71-
path.CubicTo(touchPoints[1], touchPoints[2], touchPoints[3]);
72-
canvas.DrawPath(path, bPen);
69+
using var path = new SKPath();
70+
path.MoveTo(touchPoints[0]);
71+
path.CubicTo(touchPoints[1], touchPoints[2], touchPoints[3]);
72+
canvas.DrawPath(path, bPen);
73+
}
74+
return bitmap.ToBase64String(SKEncodedImageFormat.Png);
7375
}
74-
return bitmap.ToBase64String(SKEncodedImageFormat.Png);
75-
}
7676

77-
public static T GetRandom<T>(this Random random, T[] tArray)
78-
{
79-
if (random == null) random = new Random();
80-
return tArray[random.Next(tArray.Length)];
81-
}
77+
public static T GetRandom<T>(this Random random, T[] tArray)
78+
{
79+
if (random == null) random = new Random();
80+
return tArray[random.Next(tArray.Length)];
81+
}
8282

83-
/// <summary>
84-
/// SKBitmap转Base64String
85-
/// </summary>
86-
/// <param name="bitmap"></param>
87-
/// <param name="format"></param>
88-
/// <returns></returns>
89-
public static string ToBase64String(this SKBitmap bitmap, SKEncodedImageFormat format)
90-
{
91-
using var memStream = new MemoryStream();
92-
using var wstream = new SKManagedWStream(memStream);
93-
bitmap.Encode(wstream, format, 32);
94-
memStream.TryGetBuffer(out ArraySegment<byte> buffer);
95-
return $"{Convert.ToBase64String(buffer.Array, 0, (int)memStream.Length)}";
83+
/// <summary>
84+
/// SKBitmap转Base64String
85+
/// </summary>
86+
/// <param name="bitmap"></param>
87+
/// <param name="format"></param>
88+
/// <returns></returns>
89+
public static string ToBase64String(this SKBitmap bitmap, SKEncodedImageFormat format)
90+
{
91+
using var memStream = new MemoryStream();
92+
using var wstream = new SKManagedWStream(memStream);
93+
bitmap.Encode(wstream, format, 32);
94+
memStream.TryGetBuffer(out ArraySegment<byte> buffer);
95+
return $"{Convert.ToBase64String(buffer.Array, 0, (int)memStream.Length)}";
96+
}
9697
}
9798
}

.Net6版本/VOL.WebApi/VOL.WebApi.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
1111
<OutputPath>bin\Debug\netcoreapp3.1\</OutputPath>
1212
<DocumentationFile>bin\Debug\netcoreapp3.1\VOL.WebApi.xml</DocumentationFile>
13-
<NoWarn>1701;1702;CS1591;CS8618;CS8600;CS8602;CS1572;CS1573;CS1587</NoWarn>
13+
<NoWarn>1701;1702;CS1591;CS8618;CS8600;CS8602;CS1572;CS1573;CS1587;CS1591;CS1570;CS8765;</NoWarn>
1414
</PropertyGroup>
1515

1616
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
1717
<DocumentationFile>bin\Release\netcoreapp3.1\VOL.WebApi.xml</DocumentationFile>
1818
<OutputPath>bin\Release\netcoreapp3.1\</OutputPath>
19-
<NoWarn>1701;1702;CS1572;CS1573;CS1587;CS8618;CS8600;CS8602;</NoWarn>
19+
<NoWarn>1701;1702;CS1572;CS1573;CS1587;CS8618;CS8600;CS8602;CS1591;CS1570;CS8765;</NoWarn>
2020
</PropertyGroup>
2121

2222
<ItemGroup>

.Net6版本/VOL.WebApi/VOL.WebApi.csproj.user

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
</PropertyGroup>
66
<PropertyGroup>
77
<ActiveDebugProfile>VOL.WebApi</ActiveDebugProfile>
8-
<NameOfLastUsedPublishProfile>E:\jxx\Vue.NetCore\Vue.Net\VOL.WebApi\Properties\PublishProfiles\FolderProfile.pubxml</NameOfLastUsedPublishProfile>
8+
<NameOfLastUsedPublishProfile>E:\jxx\Vue.NetCore\.Net6版本\VOL.WebApi\Properties\PublishProfiles\FolderProfile1.pubxml</NameOfLastUsedPublishProfile>
99
<Controller_SelectedScaffolderID>MvcControllerEmptyScaffolder</Controller_SelectedScaffolderID>
1010
<Controller_SelectedScaffolderCategoryPath>root/Common/MVC/Controller</Controller_SelectedScaffolderCategoryPath>
1111
</PropertyGroup>

Vue.Net/VOL.Core/Utilities/VierificationCode.cs

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -33,43 +33,44 @@ public static string RandomText()
3333
}
3434
public static string CreateBase64Imgage(string code)
3535
{
36-
Random random = new Random();
37-
//验证码颜色集合
38-
Color[] c = { Color.Black, Color.Red, Color.DarkBlue, Color.Green, Color.Orange, Color.Brown, Color.DarkCyan, Color.Purple };
39-
//验证码字体集合
40-
string[] fonts = { "Verdana", "Microsoft Sans Serif", "Comic Sans MS", "Arial", "宋体" };
36+
return VierificationCodeServices.CreateBase64Image(code);
37+
//Random random = new Random();
38+
////验证码颜色集合
39+
//Color[] c = { Color.Black, Color.Red, Color.DarkBlue, Color.Green, Color.Orange, Color.Brown, Color.DarkCyan, Color.Purple };
40+
////验证码字体集合
41+
//string[] fonts = { "Verdana", "Microsoft Sans Serif", "Comic Sans MS", "Arial", "宋体" };
4142

42-
using var img = new Bitmap((int)code.Length * 18, 32);
43-
using var g = Graphics.FromImage(img);
44-
g.Clear(Color.White);//背景设为白色
43+
//using var img = new Bitmap((int)code.Length * 18, 32);
44+
//using var g = Graphics.FromImage(img);
45+
//g.Clear(Color.White);//背景设为白色
4546

46-
//在随机位置画背景点
47-
for (int i = 0; i < 100; i++)
48-
{
49-
int x = random.Next(img.Width);
50-
int y = random.Next(img.Height);
51-
g.DrawRectangle(new Pen(Color.LightGray, 0), x, y, 1, 1);
52-
}
53-
//验证码绘制在g中
54-
for (int i = 0; i < code.Length; i++)
55-
{
56-
int cindex = random.Next(7);//随机颜色索引值
57-
int findex = random.Next(5);//随机字体索引值
58-
Font f = new Font(fonts[findex], 15, FontStyle.Bold);//字体
59-
Brush b = new SolidBrush(c[cindex]);//颜色
60-
int ii = 4;
61-
if ((i + 1) % 2 == 0)//控制验证码不在同一高度
62-
{
63-
ii = 2;
64-
}
65-
g.DrawString(code.Substring(i, 1), f, b, 3 + (i * 12), ii);//绘制一个验证字符
66-
}
67-
using (MemoryStream stream = new MemoryStream())
68-
{
69-
img.Save(stream, ImageFormat.Jpeg);
70-
byte[] b = stream.ToArray();
71-
return Convert.ToBase64String(stream.ToArray());
72-
}
47+
////在随机位置画背景点
48+
//for (int i = 0; i < 100; i++)
49+
//{
50+
// int x = random.Next(img.Width);
51+
// int y = random.Next(img.Height);
52+
// g.DrawRectangle(new Pen(Color.LightGray, 0), x, y, 1, 1);
53+
//}
54+
////验证码绘制在g中
55+
//for (int i = 0; i < code.Length; i++)
56+
//{
57+
// int cindex = random.Next(7);//随机颜色索引值
58+
// int findex = random.Next(5);//随机字体索引值
59+
// Font f = new Font(fonts[findex], 15, FontStyle.Bold);//字体
60+
// Brush b = new SolidBrush(c[cindex]);//颜色
61+
// int ii = 4;
62+
// if ((i + 1) % 2 == 0)//控制验证码不在同一高度
63+
// {
64+
// ii = 2;
65+
// }
66+
// g.DrawString(code.Substring(i, 1), f, b, 3 + (i * 12), ii);//绘制一个验证字符
67+
//}
68+
//using (MemoryStream stream = new MemoryStream())
69+
//{
70+
// img.Save(stream, ImageFormat.Jpeg);
71+
// byte[] b = stream.ToArray();
72+
// return Convert.ToBase64String(stream.ToArray());
73+
//}
7374
}
7475
}
7576
}

0 commit comments

Comments
 (0)