改变Html5画布元素的颜色深度

4
我想知道是否有一种方法可以改变HTML5 Canvas元素中图像的颜色深度,即将图像中每个像素的颜色“舍入”为低于原来颜色位深度的最近等效颜色。谢谢。

这难道不只是依赖于用户的屏幕设置吗? - feeela
我实际上想对图像数据进行处理,以创建“低分辨率”效果。 - KeithComito
3个回答

10

可以实现,而且不太难。请参考我在此处的答案:如何使用渐变映射来给HTML5画布中的图像着色。

就像在着色中一样,你只需要遍历每个像素并将RGB值改为较小的值(步长为8或16,而不是1步)

因此,对于8个步骤,你可以这样做:

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

这应该可以工作,但你应该检查边缘情况。

例如:

http://jsfiddle.net/gbBz7/


太棒了,这非常有帮助。不过我有一个快速的问题:画布默认是32位颜色深度,对吧?所以在这个例子中,您将其减少到32/4 = 8位深度?还是我的想法有误?再次感谢! - KeithComito

3
您可以通过使用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);
}

好的,那就是我想到的。我有点希望在其中有一些预定义函数,比如“更改颜色深度”......猜想那只是一厢情愿的想法,对吧? - KeithComito
@user201926:抱歉,我漏掉了一些东西...我正在设置为黑白。编辑:希望这次更好。 - pimvdb
这个答案是最佳解决方案,但是最后一行有一个错误。颜色应该被夹在整数范围内。return Math.ceil(Math.floor(c / (255 / 16)) * (255 / 16)); - Ohhh

3
我认为此功能没有内置设置。但是您可以将每个像素通道值减少到更有限的一组值。类似于以下内容:
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)

@pimvdb:很抱歉发了一个类似的答案。在我发帖之后,我没有收到有新回答的通知! - gthmb
没问题!实际上你的代码更加简洁。 - pimvdb
它不起作用!@pimvdb的答案是正确的。 - Bharata

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接