ASCII art vs. Unicode art
С приходом цветного Юникода некоторые символы могут присутствовать в системе в так называемом «стиле эмодзи», проще говоря в цвете.
«Мак» уже пару версий назад начал их показывать, я слышал, что и Винзоуз тоже
Как бы там ни было, я решил попробовать, что будет, если уменьшить доступные цветные символы до одного пискеля (чтобы остался только преобладающий цвет) и порисовать таким образом картинки в браузере. Получился бы такой
Забегая вперёд, картинка того что вышло из этой затеи — ниже. Cправа — исходник картинки, слева — Юникод, то есть, каждый пиксель этой картинки — один цветной символ Юникода, написанный (или тут надо уже говорить «нарисованный») шрифтом размером 1px.

Для начала я выяснил, что единственный браузер на «Маке», который показывает эти символы в цвете, это «Сафари», остальные показывают в лучшем случае в ч/б («Файрфокс», «Хром»), в худшем показывают
Дальше я собрал доступные цветные символы и вывел их в Сафари с размером шрифта в один пиксель и шагом в пять. Шаг нужен, чтобы символы не влияли друг на друга — разводы антиалиасинга выходят за контейнер с буквой и портят соседние символы. Получилась такая картинка:

На «баше» (ну да, я извращенец, но так просто быстрее было) накидал небольшую программу, который из этой картинки генерирует текстовый файл, состоящий из номера символа по порядку и значения цвета в формате #rrggbb:
#!/bin/bash
FILE='color-map.png'
wh=(`file $FILE | grep -oE '\S+ x [0-9]+'`)
function ColorAt {
convert $1[1x1+$2+$3] txt: | grep -oE '#[0-9A-F]{6}'
}
for (( y=0; y<${wh[2]}; y+=5 )); do
for (( x=0; x<${wh[0]}; x+=5 )); do
pos=$(( $x/5 + $y*${wh[0]}/25 ))
echo "$pos $(ColorAt $FILE $x $y)"
done
doneУтилита convert, которая используется в скрипте, это часть пакета ImageMagick.
Дальше всё просто, проходим попиксельно по картинке и берём самый близкий цвет, который у нас только есть (формула простая — минимум суммы разностей каждого компонента цвета: красной, зелёной и синей), эту часть я писал на ПХП.
$cached = [];
for ($y = 0; $y<$h; $y++) {
for ($x = 0; $x<$w; $x++) {
$cnum = imagecolorat($im, $x, $y);
if (isset($cached[$cnum])) {
$outchar = $cached[$cnum];
} else {
$mindiff = $outchar = INF;
$c = imagecolorsforindex($im, $cnum);
foreach ($colors as $colorandch) {
list($ch, $r, $g, $b, $ch) = $colorandch;
$diff = abs($r - $c['red']) + abs($g - $c['green']) + abs($b - $c['blue']);
if ($diff < $mindiff) {
$mindiff = $diff;
$outchar = $ch;
}
}
$cached[$cnum] = $outchar;
}
echo '<b>', $outchar, '</b>';
}
}Я тут ещё кеширую уже найденные цвета,
Если читателям интересно будет, выложу весь пакет. Правда, практического применения, видимо, никакого, мне интересно было сделать и помотреть хватит ли цветов для узнаваемости картинки.
Комментарии 7
, сделать
http://img-fotki.yandex.ru/get/6446/269052 … D0#196x442