验证码优化

This commit is contained in:
biss committed 2026-09-29 09:33:13 +08:00
1 parent 2880b32c92
commit 8964692448
1 file changed
+23 -13
+23 -13
View File
@@ -147,21 +147,35 @@ public sealed class SkiaTextCaptchaGenerator : ICaptchaGenerator
using var bitmap = new SKBitmap(width, 54); using var bitmap = new SKBitmap(width, 54);
using var canvas = new SKCanvas(bitmap); using var canvas = new SKCanvas(bitmap);
canvas.Clear(new SKColor(244, 248, 252)); canvas.Clear(new SKColor(244, 248, 252));
DrawNoise(canvas, width, 54, 16); DrawNoise(canvas, width, 54, 20);
using var paint = new SKPaint { IsAntialias = true }; // Use Skia's portable default typeface instead of relying on a server-installed font such as Arial.
using var font = new SKFont(SKTypeface.FromFamilyName("Arial", SKFontStyle.Bold), 30); using var font = new SKFont(SKTypeface.Default, 32) { Embolden = true };
var spacing = Math.Max(22, (width - 24) / displayText.Length); using var outlinePaint = new SKPaint
{
IsAntialias = true,
Color = new SKColor(255, 255, 255),
Style = SKPaintStyle.Stroke,
StrokeWidth = 3
};
using var textPaint = new SKPaint
{
IsAntialias = true,
Color = new SKColor(20, 48, 80)
};
var spacing = Math.Min(34, Math.Max(24, (width - 28) / displayText.Length));
var startX = width / 2f - (displayText.Length - 1) * spacing / 2f;
var metrics = font.Metrics;
var baseline = (54 - (metrics.Descent - metrics.Ascent)) / 2f - metrics.Ascent;
for (var index = 0; index < displayText.Length; index++) for (var index = 0; index < displayText.Length; index++)
{ {
var x = 12 + index * spacing + RandomNumberGenerator.GetInt32(-2, 3); var x = startX + index * spacing + RandomNumberGenerator.GetInt32(-2, 3);
var y = 38 + RandomNumberGenerator.GetInt32(-4, 5); var y = baseline + RandomNumberGenerator.GetInt32(-3, 4);
paint.Color = RandomColor(35, 145);
canvas.Save(); canvas.Save();
canvas.RotateDegrees(RandomNumberGenerator.GetInt32(-20, 21), x, y); canvas.RotateDegrees(RandomNumberGenerator.GetInt32(-20, 21), x, y);
canvas.DrawText(displayText[index].ToString(), x, y, SKTextAlign.Left, font, paint); canvas.DrawText(displayText[index].ToString(), x, y, SKTextAlign.Center, font, outlinePaint);
canvas.DrawText(displayText[index].ToString(), x, y, SKTextAlign.Center, font, textPaint);
canvas.Restore(); canvas.Restore();
} }
DrawNoise(canvas, width, 54, 10);
using var image = SKImage.FromBitmap(bitmap); using var image = SKImage.FromBitmap(bitmap);
using var data = image.Encode(SKEncodedImageFormat.Png, 100); using var data = image.Encode(SKEncodedImageFormat.Png, 100);
var challenge = new CaptchaChallenge(request.Id, type, request.ExpiresAt, var challenge = new CaptchaChallenge(request.Id, type, request.ExpiresAt,
@@ -179,10 +193,6 @@ public sealed class SkiaTextCaptchaGenerator : ICaptchaGenerator
} }
} }
private static SKColor RandomColor(int min, int max) => new(
(byte)RandomNumberGenerator.GetInt32(min, max),
(byte)RandomNumberGenerator.GetInt32(min, max),
(byte)RandomNumberGenerator.GetInt32(min, max));
private static byte RandomByte() => RandomNumberGenerator.GetBytes(1)[0]; private static byte RandomByte() => RandomNumberGenerator.GetBytes(1)[0];
} }