Ние правим визуализации на сайтове в стила на Yandex Browser
Изминаха почти два месеца, откакто Yandex зарадва някои потребители с нов продукт - Yandex Browser. Въпреки невероятната динамика на развитие на продуктите в тази област (Chrome и Firefox), Yandex успя да внесе редица нови идеи в своя браузър.От всички функции на този браузър най-много ме грабна тяхното дизайнерско решение по отношение на изображенията на сайтове в „бързи отметки“ (Speed dial). Хората обичат с очите си и затова е хубаво да виждате в новия си раздел не празна бяла страница, а цветни снимки. Единственият проблем е, че аз лично най-често гледам надписа под тази снимка или фавикона, тъй като може да бъде много трудно да го разпознаете от екранна снимка на сайт. Дизайнерите на Yandex, по мое мнение, решиха този проблем много елегантно. В тази публикация ще видим как да приложим тази идея от страна на клиента.
Същността на идеята е следната:
- Вземете favicon на сайта
- Определете доминиращия цвят в favicon
- Начертайте правоъгълник с доминиращ цвят и вмъкнете favicon в него
- За по-голяма привлекателност отгоре се наслагва градиент.
Звучи наистина много просто. Най-трудният момент тук е определянето на доминиращия цвят във фавикона. За да направим това, трябва да решим три проблема:
- Вземете favicon.
- Достъп до стойността на всеки пиксел в изображението.
- Изберете алгоритъм за определяне на доминиращия цвят.
Получаване на фавикон
За да получите favicon, можете или да напишете манипулатор на сървъра, който ще търси и върне favicon по домейн, или можете да надникнете как браузърът Yandex го прави ... И той прави това с искане към услугата Yandex със същото име. Например тази заявка:
Връщанеето снимка като тази:
Достъп до пиксели на изображението
По отношение на втората задача, единственият начин за достъп до стойностите на пикселите на изображение от страна на клиента е да се използва елементът. Като заредим изображението в платното, можем да получим стойността на произволен пиксел.
Тук обаче има проблем. Достъпът до пикселите на изображението с помощта на етикета canvas е възможен само за изображения, които са заредени от същия домейн като страницата, която ги изобразява (политиката на браузъра между домейни работи).
По този начин, за да използвате елемента canvas за търсене на доминиращия цвят във favicon, трябва да организирате прокси на вашия сървър, който да изтегли favicon (например от услугата favicon.yandex.ru) и да го върне обратно на вашата страница.
В тази връзка внедряването на такива визуализации на сайтове само от страна на клиента, уви, няма да работи. Всъщност, тъй като все още се нуждаем от сървъра като прокси за изображения, можем също така да прехвърлим изчислението на доминиращия цвят към сървъра, връщайки на страницата вече не икона, а цвят. Но как да го внедрите от страна на сървъра не е толкова интересно и много разнородно, тъй като изпълнението ще бъде различно в зависимост от езика, използван на сървъра (Python, PHP, Java). Затова ще разгледаме как да направим това на клиента с помощта на елемента canvas.
Алгоритъм за определяне на доминиращия цвят
Има много алгоритми за определяне на доминиращия цвят на изображението. Общата идея на тези алгоритми е следната. Всеки пиксел от изображението е четворка от числа R, G, B, A. Преминаваме през всички пиксели и анализираме техните компоненти по специален начин:
В нашия случай изпълнението трябва да вземе предвид две характеристики:
I. Много favicons имат прозрачни пиксели, които са представени като rgba( 0, 0, 0, 0 ), когато са начертани към елемента canvas. Тъй като игнорираме алфа канала, тези пиксели ще ни изглеждат като черни (#000000), което не е вярно. За да коригирате това, просто боядисайте платното в бяло, преди да нарисувате favicon върху него.
II. Тъй като, както е планирано, favicon ще се побере в бял кръг, тогава ако преобладаващият цвят в изображението е бял, няма да видим нито кръга, нито границите на нашия елемент. За да избегнем това, просто ще игнорираме белите пиксели във всеки алгоритъм.
Ще разгледам три различни алгоритъма за определяне на доминиращия цвят в ред на нарастване на сложността.
Алгоритъм 1. Средна стойност на цвета
Първият и най-прост алгоритъм е следният. Ние просто минаваме през всички пиксели и изчисляваме средната стойност на съответните им компонентни цветове. За да не претрупвам статията с код - всички източници са достъпни на gihub, ще покажа само резултатите от тяхната работа:
Алгоритъм 2. Евклидово разстояние
Този алгоритъм е малко по-сложен и се състои в следното. Всеки цвят е вектор в 3D пространство (r, g, b). Ние итерираме всеки пиксел и изчисляваме разстоянието му до всички останали пиксели (евклидово разстояние между два вектора). След това търсим пиксела, който е най-близо до всички останали. Цветът на този пиксел е желаният от нас цвят. Тук трябва да се отбележи, че този алгоритъм, за разлика от предишния, не създава нов цвят, а само избира от вече съществуващите в това изображение.
Алгоритъм 3. Метод на групиране на k-средните
Същността на този алгоритъме както следва. Произволно избрани k пиксела (центрове) на изображението с различни цветове. Преминаваме през всички останали пиксели и присвояваме всеки от тях на един от центровете въз основа на тяхната близост един до друг (ние изчисляваме евклидовото разстояние, както в алгоритъм 2). След това преизчисляваме центровете - задаваме тяхната стойност равна на средната сред всички свързани с него пиксели (както в алгоритъм 1). Отново преминаваме през всички пиксели и ги разпределяме към нови центрове. Правим всичко това, докато стойността на центровете спре да се променя. Желаният цвят ще бъде стойността на центъра с най-голям брой пиксели. Имайте предвид, че този метод се използва за същата цел в браузъра Chrome (http://www.quora.com/Google-Chrome/How-does-Chrome-pick-the-color-for-the-stripes-on-the-Most-visited-page-thumbnails). Резултатът от работата му за k = 3 е следният:
(за други стойности на параметъра k резултатите не са толкова значими)
Заключение
Въпросът кой от тези алгоритми е по-добър е спорен.
- Алгоритъмът за средни стойности е невероятно прост и като цяло работи, но може да стане доста объркан.
- Изчисляването през евклидовото разстояние, за моя вкус, дава доста хубав резултат и в същото време е лесно за изпълнение.
- Алгоритъмът за групиране е най-сложен. Дава най-яркото изображение и изисква най-много изчисления.
Можете да стартирате примера във вашия браузър (фавиконите са кодирани в Base64). Източници тук: github