Я пишу веб-приложение, которое принимает изображение, представленное пользователем, получает данные пикселя через элемент canvas
, выполняет некоторую обработку, а затем отображает изображение с использованием векторных фигур (используя Protovis). Он работает хорошо, но в итоге у меня несколько тысяч цветов, и я хотел бы позволить пользователю выбрать размер целевой палитры и уменьшить цветовую палитру до такого размера.
В тот момент, когда я хочу уменьшить цветовое пространство, я работаю с массивом данных пикселя RGB, например:
[[190,197,190], [202,204,200], [207,214,210], [211,214,211], [205,207,207], ...]
Я попробовал наивный вариант просто удалить наименее значимые биты из цветов, но результаты были довольно плохими. Я провел некоторое исследование алгоритмов color quantization, но пока не нашел четкого описания того, как его реализовать. Я мог бы, вероятно, разработать универсальный способ отправить это серверу, запустить его, хотя программа обработки изображений, и отправить полученную палитру обратно, но я бы предпочел сделать это в JavaScript на стороне клиента.
Есть ли у кого-нибудь пример четко объясненного алгоритма, который будет работать здесь? Цель состоит в том, чтобы уменьшить палитру в несколько тысяч цветов на меньшую палитру, оптимизированную для этого конкретного изображения.
Изменить (7/25/11): Я принял предложение @Pointy и внедрил (большинство) Leptonica MMCQ (модифицированное срединное квантование разрезов) в JavaScript. Если вам интересно, вы можете посмотреть здесь код.
Редактировать (8/5/11): libraryfck library выглядит как еще один отличный вариант для этого ( хотя я думаю, что это немного медленнее, чем моя реализация).