Жизнь, веб, XMPP, TAS, электронные самоделки

Работа с libgd

Зададимся целью написать каптчу (CAPTCHA) для ejabberd, не зависящую от ImageMagick. Это может быть актуально для небольших серверов VPS с сильно ограниченным дисковым пространством, когда нежелательно ставить целую кучу пакетов лишь ради одной только каптчи.

Мы задействуем библиотеку GD, реализующую работу с изображениями. Для простоты символы будем наносить на изображение при помощи функции gdImageStringFT, задействующей библиотеку FreeType2.

#include 
#include 
#include 
#include 

#define FONT_FILENAME "/home/wst/captcha/SketchRockwell-Bold.ttf"

int main(int argc, char **argv) {
	// Убедимся, что получили аргумент
	if(argc != 2) return 1;
	
	gdFreeFontCache();
	
	// Массив, описывающий расчётные размеры надписи
	int brect[8];
	
	// Рассчитаем размеры надписи
	gdImageStringFT(NULL, brect, 0, FONT_FILENAME, 40.0, 0.0, 0, 0, argv[1]);
	
	// Создадим изображение
	gdImagePtr image = gdImageCreateTrueColor(brect[2] - brect[6] + 6, brect[3] - brect[7] + 6);
	
	// Разные настройки
	gdImageInterlace(image, 1);
	gdImageAlphaBlending(image, 1);
	gdImageSaveAlpha(image, 1);
	
	// Фоновый цвет каптчи
	int background = gdImageColorAllocateAlpha(image, 0xFF, 0xFF, 0xFF, 0x00);
	gdImageFill(image, 0, 0, background);
	
	// Цвет символов каптчи
	int foreground = gdImageColorAllocateAlpha(image, 0xAA, 0x00, 0x00, 0x00);
	
	// Отрисовка символов каптчи
	gdImageStringFT(image, brect, foreground, FONT_FILENAME, 40.0, 0.0, 3 - brect[6], 3 - brect[7], argv[1]);
	
	// Вывод каптчи в стандартный вывод (для ejabberd)
	gdImagePng(image, stdout);
	
	// Последние штрихи
	gdImageDestroy(image);
	return 0;
}

Каптча получилась очень примитивной — зная шрифт, её можно распознать очень легко — простым сравнением символов с образцами. Поэтому при реальном использовании её рекомендуется усложнить — добавить посторонние символы и шум, реализовать смещение символов