[Из песочницы] Объединение оттенков цвета

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

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

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

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

Начал писать функцию. Исходный цвет примерно #FD9A02array_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] = Acolor[2] = array_share[3][3] = Fcolor[3] = array_share[1][1] = 5color[4] = array_share[2][2] = Acolor[5] = array_share[3][3] = Fcolor[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. Мы получили облегченный цвет одного пикселя, а если пробежаться по всей картинке 100×100пикс и каждый цвет прогнать по такому алгоритму, то получим более легкий массив, а количество оттенков в картинке вы уже сами подсчитаете.

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

© Habrahabr.ru