ASCII art vs. Unicode art

С приходом цветного Юникода некоторые символы могут присутствовать в системе в так называемом «стиле эмодзи», проще говоря в цвете.

«Мак» уже пару версий назад начал их показывать, я слышал, что и Винзоуз тоже что-то из этого набора показывает. Правда, мне непонятно насколько рисунки совпадают на разных операционных системах, думаю не совпадают, стандарт, как я понимаю, задаёт лишь смысл, цветовой исполнение и прорисовка уже на усмотрение автора шрифта.

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

Забегая вперёд, картинка того что вышло из этой затеи — ниже. Cправа — исходник картинки, слева — Юникод, то есть, каждый пиксель этой картинки — один цветной символ Юникода, написанный (или тут надо уже говорить «нарисованный») шрифтом размером 1px. Что получилось (14.70КиБ) Для начала я выяснил, что единственный браузер на «Маке», который показывает эти символы в цвете, это «Сафари», остальные показывают в лучшем случае в ч/б («Файрфокс», «Хром»), в худшем показывают какие-то обрывки («Опера»).

Дальше я собрал доступные цветные символы и вывел их в Сафари с размером шрифта в один пиксель и шагом в пять. Шаг нужен, чтобы символы не влияли друг на друга — разводы антиалиасинга выходят за контейнер с буквой и портят соседние символы. Получилась такая картинка: Карта цветов (11.91КиБ) На «баше» (ну да, я извращенец, но так просто быстрее было) накидал небольшую программу, который из этой картинки генерирует текстовый файл, состоящий из номера символа по порядку и значения цвета в формате #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>';
    }
}
Я тут ещё кеширую уже найденные цвета, всё-таки три вложенных цикла, медленно получается, кеширование позволяет уменьшить время выполнения на треть на моей картинке. Кстати, каждый символ в результате я вывожу «болдом», так насыщеннее получается.

Если читателям интересно будет, выложу весь пакет. Правда, практического применения, видимо, никакого, мне интересно было сделать и помотреть хватит ли цветов для узнаваемости картинки.
18 января 2013 22:34

DuMOHsmol (anothersite.ru)
19 января 2013, 00:02

Под Win7 нигде нормально не отображается, пробовал Firefox, Chrome, Opera, IE10.

bolk (bolknote.ru)
19 января 2013, 00:11, ответ предназначен DuMOHsmol (anothersite.ru):

Насколько я сейчас почитал, требуется указать шрифт Segoe UI, попробуйте в каких браузерах у вас отобразится вот эта страница: http://www.istartedsomething.com/uploads/emojisegoe.html

DuMOHsmol (anothersite.ru)
19 января 2013, 00:28

Символы видно во всех браузерах (большинство символов), но они не цветные. Похоже, что цвет в семёрке не поддерживается.

DuMOHsmol (anothersite.ru)
19 января 2013, 00:55

Еще заметил, что Firefox неправильно определяет кодировку.

bolk (bolknote.ru)
19 января 2013, 01:10

Кстати, если забить на все браузеры, кроме Сафари, можно выкинуть теги вокруг каждого символа, расставить <br>, сделать letter-spacing: -1px, подобрать transform: scaleX и облегчить файл на порядок.

artemp.pip.verisignlabs.com (artemp.pip.verisignlabs.com)
21 января 2013, 12:57

Поначалу не мог понять почему у меня в сафари картинка выглядит иначе. Оказалось дело в настройке Дополнения->Размер шрифта всегда не менее.

DuMOHsmol (anothersite.ru)
23 января 2013, 00:06

Вспомнил, где уже давным-давно были цветные иконки, в браузерах сименсов. Только там были не символы, а картинки вида <img localsrc="162"/>

test.pnghttp://fotki.yandex.ru/users/dumohsmol/view/701036?page=0

Ваше имя или адрес блога (можно OpenID):

Текст вашего комментария, не HTML:

Кому бы вы хотели ответить (или кликните на его аватару)