Предисловие 17 января мне, как и многим другим, прислали ссылку на статью.
жовнер о картинках в чате Скайпа - http://habrahabr.ru/blogs/skype/136395/ , и поехали! Идея классная, мы сразу начали обмениваться картинками, сгенерированными сервисом.
img4skype.com , но оказалось, что у многих они отображаются растянутыми.
Изучив фрагмент кода jovner, мы быстро обнаружили, что это можно легко исправить, удалив один пробельный символ.
Вам просто нужно исправить этот код:
так:$out .
= '<font color="#'.
strtoupper(dechex($color)).
'">███</font>';
$out .
= '<font color="#'.
strtoupper(dechex($color)).
'">██</font>';
Поэтому быстро была сделана локальная версия сервиса, позволяющая выбирать количество пробельных символов на пиксель — 2 или 3. * Однако два пробела вместо трех все равно меняют размер картинки (вместо 1:1 получается 4:3), поэтому позже мы добавили сжатие исходного изображения (1:1 => 3:4, предварительно исказив 4:3 снова получаем 1:1), если выбрано 2 пробела на пиксель.
Оптимизация
1. Сочетание похожих цветов
Идея, лежащая на поверхности и озвученная самим Жовнером, – это сочетание схожих цветов.
Если подряд идут два красных пикселя, генерируется следующий код: <font color="#ff0000">███</font><font color="#ff0000">███</font>
Совершенно очевидно, что это можно упростить: <font color="#ff0000">██████</font>
Таким образом мы сэкономим место в сообщении, занимаемое код, который освободит 29 символов, что составляет 9 или 14 пикселей (в зависимости от количества пробелов на пиксель).
Это очень важно, поскольку размер картинки ограничен максимальной длиной сообщения в Скайпе.
Данную оптимизацию уже реализовали несколько Хабраузеров, поэтому приводить весь ее код заново не вижу смысла.
Более подробно опишу только сравнение цветов.
Путем экспериментов мы пришли к следующей функции: // compare colors
function compare_clr( $c1, $c2, $max_dif, $img_px_qs )
{
$r1 = ( $c1 >> 16 ) & 0xFF;
$g1 = ( $c1 >> 8 ) & 0xFF;
$b1 = $c1 & 0xFF;
$r2 = ( $c2 >> 16 ) & 0xFF;
$g2 = ( $c2 >> 8 ) & 0xFF;
$b2 = $c2 & 0xFF;
$r_dif = abs( $r1 - $r2 );
$g_dif = abs( $g1 - $g2 );
$b_dif = abs( $b1 - $b2 );
$k = 1;
if( $img_px_qs == 1 ) // max quality
{
$def_k = 0.65;
// check difference in color channels
$dr = ( $r_dif > 0 ) ? $def_k : 0;
$dg = ( $g_dif > 0 ) ? $def_k : 0;
$db = ( $b_dif > 0 ) ? $def_k : 0;
$k = $dr + $dg + $db;
if( $k < 1 )
{
$k = 1;
}
}
else // max size
{
$k = 1;
}
$rv = true;
if( ( $r_dif*$k > $max_dif ) || ( $g_dif*$k > $max_dif ) || ( $b_dif*$k > $max_dif ) )
{
$rv = false;
}
return $rv;
}
Первые два параметра — это цвета, 3-й параметр — порог сравнения, максимальная разница между цветовыми каналами (0-255), 4-й параметр — максимальное качество или максимальный размер.
Если сравнивать между собой целые цвета, не делая разницы между каналами (r, g, b), то качество картинки оставляет желать лучшего.
Изображение очень быстро размывается.
Поэтому мы сравниваем отдельные каналы.
Если разница цветов хотя бы в одном канале превышает порог, цвета считаются разными.
Формула с коэффициентами дает наилучшее качество и лучше всего удаляет размазывание.
Он лучше подходит для сложных многоцветных картинок (фотографий).
Простое сравнение дает больший размер, но на сложных картинках появляется размытие даже при малых порогах сравнения.
Но эта формула позволяет генерировать более крупные изображения для простых смайлов и черно-белых тролльских лиц.
2. Основной цвет
Еще одна важная оптимизация, также лежащая на поверхности, — это цвет фона.«Вам также не нужно раскрашивать черный пиксель, потому что он уже черный».Черный пиксель на самом деле не черный, а стандартный.
Его цвет задается первым тегом кода, который в img4skype не имеет цвета и поэтому имеет значение по умолчанию (почти черный): <font size="1">.
Если вы добавите цвет к первому тегу шрифта, он станет цветом по умолчанию для всего изображения: <font size="1" color="#ff0000">.
И тогда для каждого красного пикселя или их последовательности не нужно вставлять тег, мы просто закрываем от предыдущего цвета и писать пробельные символы без тегов.
Если картинка представляет собой логотип/смайлик/рисунок на однородном фоне, то такая оптимизация дает очень большое увеличение размера.
Итак, прежде чем генерировать код изображения, необходимо сначала пройтись по всем пикселям и найти наиболее распространенный цвет: imagecopyresampled( $newimg, $img, 0, 0, 0, 0, $neww, $newh, $imgw, $imgh );
// find most popular color
$c_arr = array();
for( $j = 0; $j < $newh; $j++ )
{
for( $i = 0; $i < $neww; $i++ )
{
$cur_clr = imagecolorat( $newimg, $i, $j );
if( isset( $c_arr[$cur_clr] ) )
{
$c_arr[$cur_clr]++;
$found = true;
}
else
{
$c_arr[$cur_clr] = 1;
}
}
}
$max_cnt = 0;
$def_clr = 0; // most popular color
foreach( $c_arr as $key => $val )
{
if( $val > $max_cnt )
{
$max_cnt = $val;
$def_clr = $key;
}
}
3. Максимальный размер
Более того, быстро стало ясно, что люди хотят поиграть с размерами и изменить константу 800 в этой формуле: $newh = floor(sqrt(800 / $ratio));
Некоторые картинки можно сделать крупнее, код к ним можно разместить в скайпе, если заменить 800 на 1000 или 1200, а некоторые не помещаются даже на 800. Поэтому следующим шагом будет создание этой постоянной переменной, которую пользователь сможет выбирать.
Но это полумера, ведь теперь придется кропотливо повозиться с параметрами, чтобы сделать картинку максимально возможного размера и качества.
Поэтому мы сразу генерируем максимально большое изображение.
Методом деления сегмента пополам генерируем код до тех пор, пока не получим результат с максимальным значением константы в формуле выше и максимально возможной длиной, умещающейся в сообщении Skype. Теперь пользователей должно волновать только качество, оценить которое можно только человеческим глазом.
Остальное мы делаем за них.
P.S.
Обнаружив, что img4skype.com не развивается (даже реализованные идеи с готовым кодом не добавляются), мы решили создать свой аналог — skypeimg.com .Здесь реализовано все, о чем написано в этой статье.
Все функции «проверены временем» — на нашем сервисе работают с 20.01.2012.
Вот пара примеров того, как работает наш генератор (скриншоты из Скайпа в масштабе 1:1):
Я хотел бы сказать спасибо жовнер за оригинальную идею, и желаю в дальнейшем полностью реализовать простой и само собой разумеющийся функционал, чтобы не провоцировать появление конкурентов! УПД.
Комментарии учтены, сайт обновлен, весь сомнительный контент удален.
В галерее больше не отображается то, что создано пользователями, а только картинки из альбомов.
Теги: #skype #HTML #pixelart #php #messengers
-
Google Chrome Быстр, Но Не Всегда
19 Oct, 24