Изменить глубину цвета элемента HTML5 Canvas - PullRequest
4 голосов
/ 26 октября 2011

Мне было интересно, есть ли способ изменить глубину цвета изображения в элементе HTML5 Canvas, в котором цвет каждого пикселя в изображении будет «округлен» до ближайшего эквивалента с меньшей битовой глубиной цвета , например. Спасибо.

Ответы [ 3 ]

9 голосов
/ 26 октября 2011

Да, это можно сделать, и это не так уж сложно. Смотрите мой ответ здесь: Как я могу использовать карту градиента для тонирования холста HTML5 с изображением на холсте.

Как и при тонировании, все, что вам нужно сделать, - это пройти по каждому пикселю и изменить значения RGB на меньшие (шаги 8 или 16 вместо шагов 1)

Итак, за 8 шагов вы могли бы сделать:

redValue = redValue - (redValue % 32) // 155 would become 128, etc

Что должно сработать, но вы должны проверить крайние случаи.

Пример:

http://jsfiddle.net/gbBz7/

3 голосов
/ 26 октября 2011

Я не думаю, что есть встроенные настройки для этого.Но вы должны иметь возможность уменьшить значение каждого пиксельного канала до более ограниченного набора значений.Что-то вроде:

var ctx, width, height;
var factor = 8;
var pixels = ctx.getImageData(0, 0, width, height).data;

function reduce(val) {
    return Math.round(val/factor)*factor;
}

for(var i = 0, l = pixels.length; i < l; i+=4) {
    pixels[i] = reduce(pixels[i]);
    pixels[i+1] = reduce(pixels[i+1]);
    pixels[i+2] = reduce(pixels[i+2]);
}

ctx.putImageData(pixels, 0, 0)
2 голосов
/ 26 октября 2011

Вы можете перебирать каждый байт каждого цвета с помощью getImageData, поэтому вы можете применить к нему некоторые математические функции, например, представляют 8-битные цвета : http://jsfiddle.net/pimvdb/eGjak/191/.

var imgdata = ctx.getImageData(0, 0, 400, 400); // get data
var data = imgdata.data; // bytes

// 8-bit: rrr ggg bb
for(var i = 0; i < data.length; i += 4) {
    data[i]     = nearest(data[i],     8); // set value to nearest of 8 possibilities
    data[i + 1] = nearest(data[i + 1], 8);
    data[i + 2] = nearest(data[i + 2], 4);
}

ctx.putImageData(imgdata, 0, 0); // put image data to canvas

function nearest(x, a) { // will round down to nearest of a possibilities
                         // in the range 0 <= x <= 255
    return Math.floor(x / (255 / a)) * (255 / a);
}
...