Объединение оттенков цвета

в 11:23, , рубрики: hex, Алгоритмы, фотобанк, цвет

Добрый день.

В 2012 году я разрабатывал сайт фото-банк. Стояла задача реализовать довольно интересный функционал.
При загрузке новой фотографии определить несколько (8) наиболее чаще встречающихся цветов в загружаемой картинке.

Реализовать надо было на php. Но рассказывать я буду про алгоритм действий (не привязывая к определенному языку программирования).

Задача, в общем, легко реализуемая. Уменьшить картинку (чтобы снизить нагрузку на сервер) и пройтись по каждому пикселю с целью получения цвета, подсчитать их самые частые оттенки и выбрать. Но тут получилась несоответствие. На серой картинке с желтым цветком я получал оттенки черно-белого цвета и оттенки желтого. Их было очень много, а по факту нужно было получить черный, серый, белый и желтый.

Шестнадцатеричная кодировка цвета (HEX) — это типа #ABF123, таких комбинаций 16^6 = 16 777 216 оттенков цвета.

Я налил себе кофе и сел думать, как с этим бороться. Полазил на форумах, создал клик о помощи на форуме php.su, но никто не смог предложить идею. Думал день, думал два и придумал. Надо же, надо просто шестнадцатеричную систему цвета сократить на “четырехричную”.

Начал писать функцию. Исходный цвет примерно #FD9A02
array_this = [0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F] — (шестнадцатеричный массив элементов)
array_share = [0,1,2,3] [4,5,6,7] [8,9,A,B] [C,D,E,F] — (разделим его по четырем под массивам)
color_this = #AC58F3

Этап 1

Из каждого array_share берем по элементу, ключ которого равен ключу подмассива.

Из первого подмассива берем первый элемент = 0 (для получения темных оттенков).
Из второго подмассива берем второй элемент = 5.
Из третьего подмассива берем третий элемент = A (для получения темных оттенков).
Из четвертого подмассива берем четвертый элемент = F (для получения белых оттенков).

Берем каждый элемент цвета (кроме решётки) и смотрим, в каком он подмассиве:

color[1] = array_share[2][2] = A
color[2] = array_share[3][3] = F
color[3] = array_share[1][1] = 5
color[4] = array_share[2][2] = A
color[5] = array_share[3][3] = F
color[6] = array_share[0][0] = 0

new_color = color[1]color[2]color[3]color[4]color[5]color[6] = #AF5AF0

Так мы получили из цвета color_this новый цвет new_color.

Пример 2:

color_this2 = #8E79D0
Так же и получаем new_color2 = #AF5AF0
Получается, что new_color = new_color2 = #AF5AF0

Таким методом мы сократили количество оттенков 4^6 = 4096. В общем, неплохо, но хотелось бы сократить еще.

Этап 2

Приравняем каждый второй элемент цвета к предыдущему:

new_color[1] = new_color[0];
new_color[3] = new_color[2];
new_color[5] = new_color[4];

Получаем: #AF5AF0 -> #AA55FF

Итак, мы смогли сократить оттенки до 4^3 = 64. Мы получили облегченный цвет одного пикселя, а если пробежаться по всей картинке 100X100пикс и каждый цвет прогнать по такому алгоритму, то получим более легкий массив, а количество оттенков в картинке вы уже сами подсчитаете.

Если вам нужен исходник кода, сообщите, пожалуйста, в личную почту.

Автор: TroL929

Источник

Поделиться

* - обязательные к заполнению поля