Skip to content

Commit

Permalink
code refact
Browse files Browse the repository at this point in the history
  • Loading branch information
EdiWang committed Aug 11, 2024
1 parent 871e974 commit 64a8034
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 52 deletions.
109 changes: 58 additions & 51 deletions src/Edi.Captcha/CaptchaImageGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,74 +12,81 @@ namespace Edi.Captcha;

public static class CaptchaImageGenerator
{
private static readonly Random Rand = new();

public static CaptchaResult GetImage(
int width, int height, string captchaCode, string fontName, FontStyle fontStyle = FontStyle.Regular, bool drawLines = true)
{
using var ms = new MemoryStream();
var rand = new Random();

using (var imgText = new Image<Rgba32>(width, height))
{
// characters layer
float position = 0;
var averageSize = width / captchaCode.Length;
var fontSize = Convert.ToInt32(averageSize);
var imgText = new Image<Rgba32>(width, height);
DrawCaptchaText(imgText, captchaCode, fontName, fontStyle);

Font font = SystemFonts.CreateFont(fontName, fontSize, fontStyle);
using var img = new Image<Rgba32>(width, height);
DrawBackground(img);

Random random = new Random();
if (drawLines)
{
DrawRandomLines(img, width, height);
}

foreach (char c in captchaCode)
{
var x = rand.Next(5, 10);
var y = rand.Next(6, 13);
// merge layers
img.Mutate(ctx => ctx.DrawImage(imgText, 1f));
img.SaveAsPng(ms);

var degrees = random.Next(0, 10) * (random.Next(-10, 10) > 0 ? 1 : -1);
return new CaptchaResult
{
CaptchaCode = captchaCode,
CaptchaByteData = ms.ToArray(),
Timestamp = DateTime.UtcNow
};
}

var location = new PointF(x + position, y);
imgText.Mutate(ctx =>
ctx.SetDrawingTransform(Matrix3x2Extensions.CreateRotationDegrees(degrees, new(0, 0)))
.DrawText(c.ToString(), font, GetRandomDeepColor(), location));
position += TextMeasurer.MeasureBounds(c.ToString(), new(font)).Width;
}
private static void DrawCaptchaText(Image<Rgba32> imgText, string captchaCode, string fontName, FontStyle fontStyle)
{
float position = 0;
var averageSize = imgText.Width / captchaCode.Length;
var fontSize = Convert.ToInt32(averageSize);
var font = SystemFonts.CreateFont(fontName, fontSize, fontStyle);

// background layer
int low = 180, high = 255;
var nRend = rand.Next(high) % (high - low) + low;
var nGreen = rand.Next(high) % (high - low) + low;
var nBlue = rand.Next(high) % (high - low) + low;
var backColor = Color.FromRgb((byte)nRend, (byte)nGreen, (byte)nBlue);
var img = new Image<Rgba32>(width, height);
img.Mutate(ctx => ctx.BackgroundColor(backColor));
foreach (var c in captchaCode)
{
var x = Rand.Next(5, 10);
var y = Rand.Next(6, 13);
var degrees = Rand.Next(-10, 10);
var location = new PointF(x + position, y);

if (drawLines)
{
// lines
for (var i = 0; i < rand.Next(3, 7); i++)
{
var color = GetRandomDeepColor();
var startPoint = new PointF(rand.Next(0, width), rand.Next(0, height));
var endPoint = new PointF(rand.Next(0, width), rand.Next(0, height));
img.Mutate(ctx => ctx.DrawLine(color, 1, startPoint, endPoint));
}
}
imgText.Mutate(ctx =>
ctx.SetDrawingTransform(Matrix3x2Extensions.CreateRotationDegrees(degrees, new PointF(0, 0)))
.DrawText(c.ToString(), font, GetRandomDeepColor(), location));

// merge layers
img.Mutate(ctx => ctx.DrawImage(imgText, 1f));
img.SaveAsPng(ms);
position += TextMeasurer.MeasureBounds(c.ToString(), new(font)).Width;
}
}

return new()
{
CaptchaCode = captchaCode,
CaptchaByteData = ms.ToArray(),
Timestamp = DateTime.UtcNow
};
private static void DrawBackground(Image<Rgba32> img)
{
var backColor = Color.FromRgb(
(byte)Rand.Next(180, 256),
(byte)Rand.Next(180, 256),
(byte)Rand.Next(180, 256));
img.Mutate(ctx => ctx.BackgroundColor(backColor));
}

Color GetRandomDeepColor()
private static void DrawRandomLines(Image<Rgba32> img, int width, int height)
{
for (var i = 0; i < Rand.Next(3, 7); i++)
{
int redlow = 160, greenLow = 100, blueLow = 160;
return Color.FromRgb((byte)rand.Next(redlow), (byte)rand.Next(greenLow), (byte)rand.Next(blueLow));
var color = GetRandomDeepColor();
var startPoint = new PointF(Rand.Next(0, width), Rand.Next(0, height));
var endPoint = new PointF(Rand.Next(0, width), Rand.Next(0, height));
img.Mutate(ctx => ctx.DrawLine(color, 1, startPoint, endPoint));
}
}

private static Color GetRandomDeepColor()
{
int redlow = 160, greenLow = 100, blueLow = 160;
return Color.FromRgb((byte)Rand.Next(redlow), (byte)Rand.Next(greenLow), (byte)Rand.Next(blueLow));
}
}
2 changes: 1 addition & 1 deletion src/Edi.Captcha/Edi.Captcha.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Version>3.23.1</Version>
<Version>3.24.0</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Company>edi.wang</Company>
<Authors>Edi Wang</Authors>
Expand Down

0 comments on commit 64a8034

Please sign in to comment.