Создание КАПЧА-картинки в ASP.NET C#

Тема в разделе "C++ / C# / .NET", создана пользователем Евгенька, 18 мар 2015.

  1. Евгенька

    Евгенька Banned

    Регистр:
    20 фев 2015
    Сообщения:
    153
    Репутация:
    192
    Баллы:
    30
    Пол:
    Мужской
    Картинка КАПЧА
    [​IMG]

    Идея капчи заключается в том, чтобы защитить сайт от спамеров, использующих веб-ботов при регистрации новых учётных записей, отправки комментариев через веб-формы и т.д. Пользователю показывается картинка с искажённым текстом (для защиты от программ оптического распознавания). Большинство пользователей легко смогут распознать искажённый текст и ввести его для проверки, а программы - нет.

    Использование кода
    ZIP файл (который можно скачать в конце статьи) содержит исходники одного класса и двух веб-форм. Просто создайте новый проект и вставьте в него эти элементы.

    Файлы
    • CaptchaImage.cs - описывает объект CapchaImage, который создает само изображение.
    • Default.aspx, Default.aspx.cs - примеры веб-формы.
    • JpegImage.aspx, JpegImage.aspx.cs - веб-форма предназначенная для вывода JPEG изображения, а не HTML.

    Теперь подробнее рассмотрим каждый компонент и его назначение.

    CaptchaImage.cs

    Объект CaptchaImage создает изображение для текста, который будет отображаться, размеры изображения и, при необходимости, используемый шрифт.

    Основной элемент, это метод GenerateImage(), приведённый ниже, который создает растровое изображение заданной ширины и высоты. Этот метод вызывается из конструктора CaptchaImage, поэтому картинка генерируется при создании нового экземпляра объекта. При создании картинки, в первую очередь заполняется фон, используя кисть HatchBrush (чем "грязнее" будет изображение, тем труднее его будет распознать оптическим распознавалкам).

    Чтобы вписать текст в картику, необходимо определить начальный размер шрифта на основе высоты изображения и использовать метод Graphics.MeasureString(), чтобы вычислить длину отображаемого текста. Если текст превышает размеры изображения, то уменьшаем размер шрифта и проверяем снова и снова, пока подходящий размер шрифта не будет найден.
    PHP:
     // ====================================================================
        // Создание битмап-картинки.
        // ====================================================================

        
    private void GenerateImage()
        {
          
    // Создаём новое 32-битное битмап-изображение.

          
    Bitmap bitmap = new Bitmap(
            
    this.width,
            
    this.height,
            
    PixelFormat.Format32bppArgb);
          
    // Создаём графический объект для рисования.

          
    Graphics g Graphics.FromImage(bitmap);
          
    g.SmoothingMode SmoothingMode.AntiAlias;
          
    Rectangle rect = new Rectangle(00this.widththis.height);
          
    // Заполняем фон.

          
    HatchBrush hatchBrush = new HatchBrush(
            
    HatchStyle.SmallConfetti,
            
    Color.LightGray,
            
    Color.White);
          
    g.FillRectangle(hatchBrushrect);
          
    // Устанавливаем шрифт текста.

          
    SizeF size;
          
    float fontSize rect.Height 1;
          
    Font font;
          
    // Настраиваем размер шрифта, чтобы текст вписался в картинку.

          
    do
          {
            
    fontSize--;
            
    font = new Font(
              
    this.familyName,
              
    fontSize,
              
    FontStyle.Bold);
            
    size g.MeasureString(this.textfont);
          } while (
    size.Width rect.Width);
          
    // Устанавливаем формат текста.

          
    StringFormat format = new StringFormat();
          
    format.Alignment StringAlignment.Center;
          
    format.LineAlignment StringAlignment.Center;
          
    // Создаём путь используя текст и вписываем его рандомно.

          
    GraphicsPath path = new GraphicsPath();
          
    path.AddString(
            
    this.text,
            
    font.FontFamily,
            (int) 
    font.Style,
            
    font.Sizerect,
            
    format);
          
    float v 4F;
          
    PointF[] points =
          {
            new 
    PointF(
              
    this.random.Next(rect.Width) / v,
              
    this.random.Next(rect.Height) / v),
            new 
    PointF(
              
    rect.Width this.random.Next(rect.Width) / v,
              
    this.random.Next(rect.Height) / v),
            new 
    PointF(
              
    this.random.Next(rect.Width) / v,
              
    rect.Height this.random.Next(rect.Height) / v),
            new 
    PointF(
              
    rect.Width this.random.Next(rect.Width) / v,
              
    rect.Height this.random.Next(rect.Height) / v)
          };
          
    Matrix matrix = new Matrix();
          
    matrix.Translate(0F0F);
          
    path.Warp(pointsrectmatrixWarpMode.Perspective0F);
          
    // Рисуем текст.

          
    hatchBrush = new HatchBrush(
            
    HatchStyle.LargeConfetti,
            
    Color.LightGray,
            
    Color.DarkGray);
          
    g.FillPath(hatchBrushpath);
          
    // Добавляем случайный шум.

          
    int m Math.Max(rect.Widthrect.Height);
          for (
    int i 0< (int) (rect.Width rect.Height 30F); i++)
          {
            
    int x this.random.Next(rect.Width);
            
    int y this.random.Next(rect.Height);
            
    int w this.random.Next(50);
            
    int h this.random.Next(50);
            
    g.FillEllipse(hatchBrushxywh);
          }
          
    // Освобождаем ресурсы.

          
    font.Dispose();
          
    hatchBrush.Dispose();
          
    g.Dispose();
          
    // Устанавливаем изображение.

          
    this.image bitmap;
        }
    После того как шрифт установлен, используем GraphicsPath(), чтобы преобразовать текст в набор линий и кривых. Чтобы исказить изображение текста, используем метод GraphicsPath.Warp() с некоторыми случайно сгенерированными значениями. Потом опять используем "грязную" кисть чтобы сам текст был не только искажённым, но и загрязнённым.

    Для полного искажения добавляем небольшие случайные помарки к общему изображению. Можно экспериментировать с любыми типами помарок, только не перестарайтесь, иначе некоторые посетители с нарушениями зрения не смогут разобрать текст на картинке.

    Default.aspx

    Это самый простой образец веб-формы, которая содержит всего несколько основных элементов: тег картинки < IMG >, текстовое поле и кнопку "Отправить".

    PHP:
    <form id="Default" method="post" runat="server">
          <
    img src="JpegImage.aspx"><br>
          <
    p>
            <
    strong>Введите кодизображённый на картинке:</strong><br>
            <
    asp:TextBox id="CodeNumberTextBox" runat="server"></asp:TextBox>
            <
    asp:Button id="SubmitButton" runat="server" Text="Отправить">
            </
    asp:Button><br>
          </
    p>
          <
    p>
            <
    em class="notice">
              (
    ВниманиеЕсли Вы не смогли распознать код на картинке,<br>
              
    обновите страницу для смены кода.)</em>
          </
    p>
          <
    p><asp:Label id="MessageLabel" runat="server"></asp:Label></p>
        </
    form>
    Обратите внимание, что атрибут SRC тэга < IMG > указывает на веб-форму JpegImage.aspx.

    Код для Default.aspx просто генерирует случайную строку текста для картинки и подтверждает, что этот текст, действительно введен пользователем при сабмите формы. Основной момент заключается в том, что текстовой строка сохраняется в объекте Session.
    PHP:
     private void Page_Load(object senderSystem.EventArgs e)
        {
          if (!
    this.IsPostBack)
            
    // Генерируем случайный код и сохраняем его объекте Сессии (Session).

            
    this.Session["CaptchaImageText"] = GenerateRandomCode();
          else
          {
            
    // При постбэке проверяем ввод пользователя.

            
    if (this.CodeNumberTextBox.Text ==
              
    this.Session["CaptchaImageText"].ToString())
            {
              
    // Показываем информационное сообщение.

              
    this.MessageLabel.CssClass "info";
              
    this.MessageLabel.Text "Correct!";
            }
            else
            {
              
    // Показываем сообщение об ошибке.

              
    this.MessageLabel.CssClass "error";
              
    this.MessageLabel.Text "ERROR: Incorrect, try again.";
              
    // Очищаем ввод и создаём новый случайный код.

              
    this.CodeNumberTextBox.Text "";
              
    this.Session["CaptchaImageText"] = GenerateRandomCode();
            }
          }
        }
    Хранения текстовой строки в объекте Session сделано для того, чтобы она была доступна для JpegImage.aspx.

    JpegImage.aspx

    Для этой веб-формы не нужен HTML-код - она просто генерирует JPEG-картинку (весь html-код, который там есть сгенерирован по умолчанию Вижуал Студией при создании файла).

    В коде мы сперва создаем объект CaptchaImage (при создании объекта происходит генерация самой картинки), используя текст извлекаемый из объекта Session.
    PHP:
     private void Page_Load(object senderSystem.EventArgs e)
        {
          
    // Генерируем КАПЧА-картинку, используя текст, сохранённый в объекте Session.

          
    CaptchaImage ci = new CaptchaImage(
            
    this.Session["CaptchaImageText"].ToString(),
            
    20050"Century Schoolbook");
          
    // Прописываем в заголовках тип картинки JPEG.

          
    this.Response.Clear();
          
    this.Response.ContentType "image/jpeg";
          
    // Записываем изображение выходной поток в формате JPEG.

          
    ci.Image.Save(this.Response.OutputStreamImageFormat.Jpeg);
          
    // Освобождаем объект капча-картинки.

          
    ci.Dispose();
        }
    Затем меняем заголовки HTTP-ответа на Content-type="image/jpeg", чтобы браузер клиента знал, что мы посылаем ему изображение.

    В заключании получаем растровое изображение с CaptchaImage.Image и записываем его в поток HTTP-ответа в формате JPEG. Для этого используется метод Save(). Можно так же установить любые другие форматы изображения, естевственно понадобится изменить заголовок Content-type соответствующим образом.

    Важный момент
    Так как класс CaptchaImage содержит объект Bitmap, то в конце вызывается метод Dispose(), чтобы освободить ресурсы когда CaptchaImage будет уничтожен.

    Скачать исходник - 6 кб (кликабельно)
     
  2. kuznechik555

    kuznechik555 Новичок

    Регистр:
    6 окт 2014
    Сообщения:
    3
    Репутация:
    0
    Баллы:
    0
    Пол:
    Мужской
Похожие Темы
  1. rekh_5
    Ответов:
    0
    Просмотров:
    464
Загрузка...