了解JavaScript灰度算法的工作原理(不使用jQuery)
今天,我正在寻找一种将彩色图像转换为灰度的算法,结果并不长,我在下面的文章中找到了它 本文包含以下代码片段了解JavaScript灰度算法的工作原理(不使用jQuery),javascript,image,algorithm,grayscale,Javascript,Image,Algorithm,Grayscale,今天,我正在寻找一种将彩色图像转换为灰度的算法,结果并不长,我在下面的文章中找到了它 本文包含以下代码片段 var imgObj = document.getElementById('js-image'); function gray(imgObj) { var canvas = document.createElement('canvas'); var canvasContext = canvas.getContext('2d'); var imgW = imgO
var imgObj = document.getElementById('js-image');
function gray(imgObj) {
var canvas = document.createElement('canvas');
var canvasContext = canvas.getContext('2d');
var imgW = imgObj.width;
var imgH = imgObj.height;
canvas.width = imgW;
canvas.height = imgH;
canvasContext.drawImage(imgObj, 0, 0);
var imgPixels = canvasContext.getImageData(0, 0, imgW, imgH);
for (var y = 0; y < imgPixels.height; y++) {
for (var x = 0; x < imgPixels.width; x++) {
var i = (y * 4) * imgPixels.width + x * 4;
var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
imgPixels.data[i] = avg;
imgPixels.data[i + 1] = avg;
imgPixels.data[i + 2] = avg;
}
}
canvasContext.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);
return canvas.toDataURL();
}
imgObj.src = gray(imgObj);
for (var i = 0; i < imgPixels.data.length; i = i + 4) {
var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
imgPixels.data[i] = avg;
imgPixels.data[i + 1] = avg;
imgPixels.data[i + 2] = avg;
}
为什么这里我们增加4
如果您能回答此算法的工作原理,我将不胜感激。画布数据以RGBA(红色、绿色、蓝色和称为“alpha”的透明度值)交错格式提供给您。每个通道每像素需要一个字节,您有四个通道,因此每个像素有四个值。由于通道是交错的,因此可以按4递增,以逐步通过像素 参考资料:
- (由
返回的结构)getImageData()
console.log(imgPixels)
并获取大量数据数组。使用console.log(imgPixels.data.length)
获取666000号。如果图像是获得的,如何获取此数字500px*333px
@Mikhail 500*333*4=666000Oh。我想我明白了500*333=166500
由于每个像素有4个通道(RGBA)相乘166500*4=666000
很抱歉,但是。。。你能告诉我关于这一行的情况吗(例如在回答中)vari=(y*4)*imgPixels.width+x*4代码>(来自第一个代码段)?在这种情况下(当图像500px*333px
时),我有667332
而不是666000
,并且在这种情况下,对于skipalpha
channel@Mikhail像素数据作为一维阵列提供。它们不是使用单个for
循环来迭代该数组,而是迭代x
和y
,然后将其转换为像素数据数组的索引i
。您询问的特定行执行从x,y
到索引的转换。我认为如果示例使用公式vari=(y*imgPixels.width+x)*4,可能会更容易理解代码>。请记住,索引通常从零开始,在数组大小之前结束。基于原始公式:332*4*500+499*4=665996
for (var i = 0; i < imgPixels.data.length; i = i + 4) {
var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
imgPixels.data[i] = avg;
imgPixels.data[i + 1] = avg;
imgPixels.data[i + 2] = avg;
}
for (var i = 0; i < imgPixels.data.length; i = i + 4) {
var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
imgPixels.data[i] = avg;
imgPixels.data[i + 1] = avg;
imgPixels.data[i + 2] = avg;
}
for (var i = 0; i < imgPixels.data.length; i = i + 4) {