Сделайте CAPTCHA изображения в C#

CAPTCHA (полностью автоматизированный публичный тест Тьюринга, чтобы рассказать о компьютерах и людях) - это искаженные изображения слов, которые некоторые веб-сайты заставляют вас вводить, чтобы доказать, что вы являетесь человеком, а не автоматизированным процессом. Идея состоит в том, чтобы исказить символы на изображении, поэтому было бы трудно, чтобы приложение оптического распознавания символов (OCR) прочитало их, но так было бы легко прочитать его людям.

В этом примере используются относительно большие шрифты, поэтому символы имеют тенденцию перекрываться интересными способами, которые трудно распознать программу OCR.

Обратите внимание, что некоторые мошенники передают изображения CAPTCHA сторонним работникам, которые платят около 0,75 доллара за тысячу изображений, поэтому это не является надежной техникой. Однако даже этого низкого уровня стоимости достаточно, чтобы отсеять некоторый процент мошенников.

Следующий способ MakeCaptchaImage создает изображение CAPTCHA.

private Random Rand = new Random();

// Создаем изображение для текста.
private Bitmap MakeCaptchaImge(string txt,
    int min_size, int max_size, int wid, int hgt)
{
    // Создаем растровое изображение и связанный с ним объект Graphics.
    Bitmap bm = new Bitmap(wid, hgt);
    using (Graphics gr = Graphics.FromImage(bm))
    {
        gr.SmoothingMode = SmoothingMode.HighQuality;
        gr.Clear(Color.White);

        // Посмотрите, сколько места доступно для каждого персонажа.
        int ch_wid = (int)(wid / txt.Length);

        // Рисуем каждый символ.
        for (int i = 0; i < txt.Length; i++)
        {
            float font_size = Rand.Next(min_size, max_size);
            using (Font the_font = new Font("Times New Roman",
                font_size, FontStyle.Bold))
            {
                DrawCharacter(txt.Substring(i, 1), gr,
                    the_font, i * ch_wid, ch_wid, wid, hgt);
            }
        }
    }

    return bm;
}

Этот метод сначала создает Bitmap нужного размера, устанавливает его свойство SmoothingMode и очищает его. Затем метод вычисляет ширину, которая может допускать каждый символ. Затем код перебирает символы сообщения. Для каждого символа он генерирует случайный размер шрифта и создает шрифт такого размера. Наконец, код вызывает следующий DrawCharacter метод для рисования символа.

// Нарисуем деформированный символ в этом положении.
private int PreviousAngle = 0;
private void DrawCharacter(string txt, Graphics gr,
    Font the_font, int X, int ch_wid, int wid, int hgt)
{
    // Центрируем текст.
    using (StringFormat string_format = new StringFormat())
    {
        string_format.Alignment = StringAlignment.Center;
        string_format.LineAlignment = StringAlignment.Center;
        RectangleF rectf = new RectangleF(X, 0, ch_wid, hgt);

        // Преобразование текста в путь.
        using (GraphicsPath graphics_path = new GraphicsPath())
        {
            graphics_path.AddString(txt,
                the_font.FontFamily, (int)(Font.Style),
                the_font.Size, rectf, string_format);

            // Произвольные случайные параметры деформации.
            float x1 = (float)(X + Rand.Next(ch_wid) / 2);
            float y1 = (float)(Rand.Next(hgt) / 2);
            float x2 = (float)(X + ch_wid / 2 +
                Rand.Next(ch_wid) / 2);
            float y2 = (float)(hgt / 2 + Rand.Next(hgt) / 2);
            PointF[] pts = {
            new PointF(
                (float)(X + Rand.Next(ch_wid) / 4),
                (float)(Rand.Next(hgt) / 4)),
            new PointF(
                (float)(X + ch_wid - Rand.Next(ch_wid) / 4),
                (float)(Rand.Next(hgt) / 4)),
            new PointF(
                (float)(X + Rand.Next(ch_wid) / 4),
                (float)(hgt - Rand.Next(hgt) / 4)),
            new PointF(
                (float)(X + ch_wid - Rand.Next(ch_wid) / 4),
                (float)(hgt - Rand.Next(hgt) / 4))
        };
            Matrix mat = new Matrix();
            graphics_path.Warp(pts, rectf, mat,
                WarpMode.Perspective, 0);

            // Поворачиваем бит случайным образом.
            float dx = (float)(X + ch_wid / 2);
            float dy = (float)(hgt / 2);
            gr.TranslateTransform(-dx, -dy, MatrixOrder.Append);
            int angle = PreviousAngle;
            do
            {
                angle = Rand.Next(-30, 30);
            } while (Math.Abs(angle - PreviousAngle) < 20);
            PreviousAngle = angle;
            gr.RotateTransform(angle, MatrixOrder.Append);
            gr.TranslateTransform(dx, dy, MatrixOrder.Append);

                        gr.FillPath(Brushes.Blue, graphics_path);
            gr.ResetTransform();
        }
    }
}

Этот метод делает объект StringFormat центрировать символ в прямоугольнике. Затем он создает прямоугольник, который будет удерживать символ.

Далее код создает объект GraphicsPath и добавляет в него символ в правильной позиции. Он случайным образом выбирает некоторые точки в области персонажа и использует метод GraphicsPath объекта Warp, чтобы деформировать ограничивающий прямоугольник символа на эти точки, искажая изображение персонажа.

Далее код применяет преобразование к объекту Graphics для поворота символа вокруг его центра на случайный угол. В тестах я видел много символов с одинаковыми вращениями, поэтому я добавил статическую переменную и цикл, чтобы гарантировать, что вращение каждого персонажа отличается от вращения предыдущего символа не менее чем на 20 градусов.

Источник: http://csharphelper.com/blog/2015/01/make-captcha-images-in-c/

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Adblock
detector