using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CapchaLibrary
{
public class CapchaGenerator
{
///
/// Базовый конструктор, создающий генератор капчи по умолчанию
///
public CapchaGenerator()
{
ValidCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
SymbolsCount = 6;
NoiseCount = 25;
random = new Random(DateTime.Now.Microsecond);
}
///
/// Конструктор генератора, позволяющий задавать используемые при создании капчи символы, количество символов в капче и количество шума
///
/// Используемые при создании символы
/// Количество символов в капче
public CapchaGenerator(string validCharacters, int symbolsCount, int noiseCount)
{
ValidCharacters = validCharacters;
SymbolsCount = symbolsCount;
NoiseCount = noiseCount;
random = new Random(DateTime.Now.Microsecond);
}
///
/// Строка состоящая из символов, использующихся при создании капчи
///
public string ValidCharacters { get; init; }
///
/// Количество символов в капче
///
public int SymbolsCount { get; init; }
///
/// Количество шума на капче
///
public int NoiseCount { get; init; }
///
/// Метод генерации капчи
///
/// Данные по сгенерированной капче
public CapchaData GenerateCapcha()
{
string capchaCode = GenerateCapchaCode();
Bitmap capcha = GenerateCapcha(capchaCode);
return new CapchaData(capcha, capchaCode);
}
private readonly Dictionary CapchaColors = new Dictionary()
{
{ 0, (Color.Aquamarine, Brushes.Aqua) },
{ 1, (Color.PapayaWhip, Brushes.Pink) },
{ 2, (Color.Coral, Brushes.IndianRed) },
};
private readonly Random random;
///
/// Метод генерации кода капчи
///
/// Код капчи
private string GenerateCapchaCode() =>
new string(Enumerable.Repeat(ValidCharacters, SymbolsCount)
.Select(s => s[random.Next(s.Length)])
.ToArray());
///
/// Метод генерации изображения капчи
///
/// Код капчи
/// Изображение капчи
private Bitmap GenerateCapcha(string capchaCode)
{
Bitmap capcha = new(2560, 1440);
(Color, Brush) colors = GetRandomCapchaColor();
using (Graphics graphics = Graphics.FromImage(capcha))
{
graphics.Clear(colors.Item1);
int SymbolX = 150;
int SymbolY = 650;
foreach (char symbol in capchaCode)
{
int NextSymbolY = SymbolY + (random.Next(0, 600) - 600);
graphics.DrawString(symbol.ToString(), new Font("Comic Sans MS", 320, FontStyle.Bold), colors.Item2, new PointF(SymbolX, NextSymbolY));
SymbolX += 360;
}
for(int noiseCounter = 0; noiseCounter < NoiseCount; noiseCounter++)
{
graphics.DrawLine(new Pen(Brushes.DarkBlue, 5)
, new Point(random.Next(0, 2560), random.Next(0, 1440))
, new Point(random.Next(0, 2560), random.Next(0, 1440)));
}
}
return capcha;
}
private (Color, Brush) GetRandomCapchaColor()
{
(Color, Brush) brush;
CapchaColors.TryGetValue(random.Next(0,3), out brush);
return brush;
}
}
}