PHP: Генератор картинок шрифтов

Символ из шрифта на картинке
Понадобилось написать генератор картинок символов из различных шрифтов(всех что есть в системе). Всё просто - символ чёрного цвета в центре изображения на белом фоне, расфасованные по папочкам по названию шрифта и размеру - путь получится в виде symbols/FONT/SIZE/SYMBOL.jpg

Вот такую программку на скорую руку пришлось написать.
В переменной RESOLUTIONS разрешения через запятую, ширина от высоты отделенна буквой икс(x). FONTS_DIR определяет где лежат шрифты. Можно даже узкать "/", или в случае винды "c:/", вот только ждать долго придётся :) Переменная SYMBOLS определяет какие символы нужно рисовать на картинках.

<?php

$RESOLUTIONS = "20x20,20x40,20x55,20x70,40x20,40x40,40x55,40x70,"
. "55x20,55x40,55x55,55x70";

$FONTS_DIR = '/usr/share/fonts/';

$SYMBOLS = "0123456789";
$SYMBOLS = "abc123";

$FONTS = array();
$dir_handle = @opendir($FONTS_DIR) or die("Unable to open $FONTS_DIR");
list_dir($dir_handle, $FONTS_DIR);

function list_dir($dir_handle,$path) {
while (false !== ($file = readdir($dir_handle))) {
if ($file == '.' || $file =='..' ) continue;
$dir = $path.'/'.$file;
if(is_dir($dir)) {
$handle = @opendir($dir) or die("undable to open file $file");
list_dir($handle, $dir);
} else {
if (strpos($file, 'ttf') == false) continue;
$GLOBALS['FONTS'][] = "{$path}/{$file}";
}
}
closedir($dir_handle);
}

$RESOLUTIONS = explode(',', $RESOLUTIONS);

echo "Total fonts: " . count($FONTS) . "\n";

$odir = './symbols/';
if (!file_exists($odir)) mkdir($odir);
foreach ($FONTS as $font) {
$ofdir = "{$odir}" . basename($font) . '/';
if (!file_exists($ofdir)) mkdir ($ofdir);

echo "Font " . basename($font) . "\n";
foreach ($RESOLUTIONS as $res) {
@list($width, $height) = explode('x', $res);
if ($width <= 0 || $height <= 0) continue;
echo " * Resolution {$res}: ";

$ordir = "{$ofdir}{$res}/";
if (!file_exists($ordir)) mkdir ($ordir);

$sym_len = strlen($SYMBOLS);
for($num = 0; $num < $sym_len; $num++) {
echo "{$SYMBOLS[$num]} ";

$angle = 0;
$points = 20;
$im = imagecreatetruecolor($width, $height);
$black = ImageColorAllocate($im, 0x00, 0x00, 0x00);
$white = ImageColorAllocate($im, 0xff, 0xff, 0xff);

imagefilledrectangle($im, 0, 0, $width, $height, $white);

$size = ImageTTFBBox($points, $angle, $font, $SYMBOLS[$num]);
$cX = ($width - (abs($size[2]- $size[0]))) / 2;
$cY = (($height - (abs($size[5] - $size[3]))) / 2 + abs($size[5] - $size[3]));
if ($cX <= 0) $cX = ($width - $points) / 2;
if ($cY <= 0) $cY = ($height - $points) / 2;

ImageTTFText($im, $points, $angle, ($cX - 1), $cY, $black, $font, $SYMBOLS[$num]);

imagejpeg($im, "{$ordir}/{$SYMBOLS[$num]}.jpg");
}
echo "\n";
}
}
?>

Запускаем

#php n_generator.php
. . . . . .
Font Dyuthi3.ttf
* Resolution 20x20: a b c 1 2 3
* Resolution 20x40: a b c 1 2 3
* Resolution 20x55: a b c 1 2 3
* Resolution 20x70: a b c 1 2 3
* Resolution 40x20: a b c 1 2 3

Меня сильно удивило отсутствие перечисления(enumeration) шрифтов средствами пхп. Т.е. php не может определить шрифты, установленные в системе. По крайней мере я в мануале не нашёл. Поэтому пришлось рекурсивно перебирать папку со шрифтами и находить в ней truetype

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

Бенчмарк

За 15 секунд сгенерированно 16 065 объектов, в сумме 21,5 МБ. А руками слабо? :)