Улучшаем картинки в чате Skype (обновлено)

Предисловие



17 января мне, как и многим другим, прислали ссылку на статью zhovner про картинки в чате скайпа — http://habrahabr.ru/blogs/skype/136395/, и понеслось!
Идея прикольная, мы тут же начали перекидываться картинками, сгенерированными сервисом img4skype.com, но оказалось что у многих они отображаются растянуто.





Просмотрев фрагмент кода zhovner мы быстро обнаружили что это легко можно исправить, убрав один пробельный символ.

Нужно всего лишь исправить такой код:

$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. Объединение похожих цветов


Идея, лежащая на поверхности и озвученная самим zhovner — это объединение похожих цветов.
Если подряд идут два пикселя красного цвета то генерируется такой код:

<font color="#ff0000">███</font><font color="#ff0000">███</font>


Вполне очевидно что это можно упростить:

<font color="#ff0000">██████</font>


Так мы сэкономим место в сообщении, занимаемое кодом <font color="#ff0000"></font>, что освободит нам 29 символов, а это 9 или 14 пикселей (в зависимости от количества пробелов на пиксель).
Это очень важно, потому что размер картинки ограничен максимальной длиной сообщения в Skype.

Эта оптимизация уже реализована несколькими хабраюзерами, поэтому не вижу смысла еще раз приводить ее код целиком.
Опишу подробнее только сравнение цветов.

Экспериментальным путем мы пришли к следующей функции:

// 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 цвет то он будет дефолтным цветом для всей картинки:

<font size="1" color="#ff0000">...


И тогда для каждого красного пикселя или их последовательности нет нужды вставлять тег <font color="#ff0000"></font>, просто закрываем <font> от предыдущего цвета и пишем пробельные символы без тегов.

Если картинка — это лого/смайлик/рисунок на однородном фоне, то эта оптимизация дает очень большое увеличение размера.

Итак, перед генерацией кода картинки надо предварительно пройти по всем пикселям и найти наиболее часто встречающийся цвет:

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):



Хотелось бы сказать спасибо zhovner за оригинальную идею, и пожелать в будущем до конца реализовывать простой и сам собой напрашивающийся функционал, чтобы не провоцировать появление конкурентов!

UPD. Замечания учтены, сайт обновлен, весь сомнительный контент убран. В галерее больше не показывается то что генерится пользователями, только картинки из альбомов.

Похожие публикации

Средняя зарплата в IT

110 500 ₽/мес.
Средняя зарплата по всем IT-специализациям на основании 7 138 анкет, за 2-ое пол. 2020 года Узнать свою зарплату
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 30

    +29
    Молодая мама трахается с сыном на камеру без смс.
    Нет уж, спасибо. Пользуйтесь сами.
      0
      Сорри, сейчас настроим фильтры. Спасибо за инфо.
        +5
        И на чистый nginx с php-fpm перенесите… Лежит…
          0
          В ближайшее время обязательно займемся, лежит совсем.
            +1
            Все, настроил nginx + php-fpm.
            artamonovg — еще раз спасибо за совет, на nginx все заработало
          +4
          Зато теперь полно сгенерированых порно картинок
            –1
            В галерее показываются те картинки которые вставляются пользователями. Предлагаешь ввести модерацию? ;)
              +5
              Почему бы и нет?
                –1
                Конечно ввести, на вас же дело заведут
              –1
              Для нашей страны адалт реклама не показывалась, поэтому и возник косяк. Убрано.
                +2
                В Беларуси порно нет!
            –2
            Еще и идею, и код украли. Лучше бы первоначальному проекту помогли.
              0
              Всмысле «украли»? От первоначального проекта кода в существующей версии исчезающе мало. Разве запрещено создавать аналоги? Любой человек, в том числе и создатели изначального проекта, могут использовать приведенный мною код.
                +1
                Пожалуй стоит внести бОльшую ясность.

                Идея и первенство принадлежит img4skype. Этого никто не оспаривает, без идеи zhovner скорее всего не было бы и нашего сервиса. У нас об этом даже написано на странице с руководством.
                Это железобетонный факт, который будет таким всегда.

                Но почему не имеет право на жизнь другая реализация этой идеи? Сначала мы сделали для себя и друзей локальную версию, которая восполняла для нас отсутствующий функционал оригинала. А потом решили сделать на ее основе свой сервис.
              +5
              Рассадник порнорекламы!
                0
                Извиняюсь, в фильтрах запретил все порно, в ближайшее время должно исчезнуть навсегда!
                  0
                  Нельзя от гугла или яндекса поставить рекламу?
                  «Женщина родила ужасное существо — это напугало даже врачей!»
                    0
                    У нас не поисковый трафик.

                    Между прочим сейчас глянул статистику — до того как забанил по баннерам адалт тематики было 70% кликов. Да и в галерее сиськи стали самыми популярными картинками без всякого участия с нашей стороны. Так что у этого контента много поклонников.

                    Надеюсь тему не заполонят стоны «почему пропали нормальные картинки» после того как уберем галерею в нынешнем виде?
                0
                Я боюсь, вам скоро напишут из Скайпа. Почитайте внимательно где и как можно использовать название Skype.
                  +5
                  Кому нужен лежащий труп, тьфу…
                    0
                    Молимся и оживляем :)
                      0
                      Не ожидал что после поста на хабре все настолько резко повалится — 2 недели все без проблем работало на апаче с посещениями больше 1 тыс в день. Настроил nginx, труп ожил.
                    0
                    Анимация-то когда будет?
                      0
                      вопрос к Skype
                      0
                      все таки линк в конце немного напряг…
                        +3
                        В новой версии скайпа 5.8.0.154 больше нет возможности отправлять HTML. Но при этом код отправленный с версии младше, отображается в новой версии нормально. Для отправки кода нужна версия ≤5.7. Так что со временем это всё будет не актуально.

                        Кроме того, существование доменов содержащих *skype* в названии тоже вопрос времени. Через неделю после создания img4skype.com мне пришло письмо от юридической конторы представляющей интересы скайпа с таким содержанием:

                        We contact you today regarding intellectual property concerns with respect to the Internet
                        domain name <img4skype.com> (the “Domain”) and the website resolving under the
                        Domain. The Domain contains the famous Skype trademark and the website uses a Skype
                        logo (see Annex A), but Skype never authorized you to exploit the “SKYPE” term in a
                        domain name or to use Skype logos on your website(s). Nor did Skype never authorize you
                        to exploit its intellectual property in any manner. In light of this, Skype requires that you
                        immediately:
                        * Stop using the Domain and transfer the Domain to Skype; and
                        * Remove any and all Skype logos from your website(s).
                        While Skype is pleased when others enthusiastically promote Skype, Skype’s policies prohibit
                        the registration or acquisition of Skype-related domain names by third parties (see paragraph
                        — 2 — 7.4 of Skype’s Terms of Use, located at www.skype.com/intl/enus/legal/terms/tou). Similarly, confusing display of Skype’s trademark or logos, amongother things, are actions prohibited by Skype’s terms and policies because they might harm Skype or confuse consumers. These policies serve to ensure that information is free-flowing and accurate about what Skype is and where a legitimate copy can be obtained.

                        Несмотря на то, что в перечисленных странах где Skype является зарегистрированной торговой маркой нет Украины, а домен зарегистрирован через украинского регистратора, домен вероятнее всего отберут через арбитраж ICANN.
                          0
                          Да, признаки затухания темы налицо. Поэтому дальнейшее вложение сил в развитие проекта на сегодня под вопросом.
                          zhovner — сколько мы тебе должны? ;)
                            +3
                            Мда, кладезь порева. Ну и грузился минут 20.
                              0
                              Не было желание даже попробывать сгенерировать картинку, так как одно порно кругом, что в рекламе, что в галерее. Даа, «хороший» же у Вас аналог получился :(
                                +1
                                Вся адалт тематика в рекламе должна быть заблокирована. До сих пор есть? Для меня не отображается, даже через российские прокси.
                                По поводу галереи — если так много жалоб то вообще не будем показывать последние картинки от посетителей, заменим на набор альбомов, где будут выбранные нами картинки по разным темам.

                                Странно только что в коментах к img4skype нет ни одного замечания про контент, хотя там галерея была заполнена тем же самым.

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

                              Самое читаемое