Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/403.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从HTML5画布垂直迭代像素_Javascript_Canvas - Fatal编程技术网

Javascript 从HTML5画布垂直迭代像素

Javascript 从HTML5画布垂直迭代像素,javascript,canvas,Javascript,Canvas,我试图在图像中找到第一个包含数据的垂直和水平行 我很容易得到第一个水平行,当调用getImageData时,得到的像素数据数组是逐行水平存储的。我有这样的数据: var data = context.getImageData(0, 0, width, height).data; var heightFirst = 0; for (var r = 0; r <= data.length; r += 4) { if (data[r + 3] > 0) { var

我试图在图像中找到第一个包含数据的垂直和水平行

我很容易得到第一个水平行,当调用
getImageData
时,得到的像素数据数组是逐行水平存储的。我有这样的数据:

var data = context.getImageData(0, 0, width, height).data;
var heightFirst = 0;

for (var r = 0; r <= data.length; r += 4) {
    if (data[r + 3] > 0) {
        var y = (r / width) / 4;
        heightFirst = y;
        break;
    }
}
var data=context.getImageData(0,0,宽度,高度);
var heightFirst=0;
对于(var r=0;r 0){
变量y=(r/宽度)/4;
高度优先=y;
打破
}
}
我现在需要垂直地迭代数据。我意识到这可能是通过使用嵌套for循环完成的,并执行如下操作:

for (var r = 0; r <= data.length; r += 4) {
    for (var c = 0; c < canvasHeight; c++) {    
        if (data[(r + 3) + (c * width)] > 0) {

        }
    }
}
for (var c = 0; c < canvas.width; c ++) {
    for (var r = 0; r <= data.length; r += ((4 * canvas.width) + (c * 4))) {
        if (data[r + 3] > 0) {
            firstX = c;
        }
    }
}
for(var r=0;r 0){
}
}
}
我不确定具体的实现/计算,有人能帮我吗

编辑

正如@bobbybee和@danielpolencic所提到的,一个增加4*宽度的循环将增加一个垂直列:

for (var r = 0; r <= data.length; r += (4 * width)) {
  if (data[r + 3] > 0) {
    // do whatever
  }
}
for(var r=0;r 0){
//做任何事
}
}
但是,这仅获取第一列像素的信息。我想下一步是重复上面的循环,但使用如下循环增加列数(根据颜色数据乘以4):

for (var r = 0; r <= data.length; r += 4) {
    for (var c = 0; c < canvasHeight; c++) {    
        if (data[(r + 3) + (c * width)] > 0) {

        }
    }
}
for (var c = 0; c < canvas.width; c ++) {
    for (var r = 0; r <= data.length; r += ((4 * canvas.width) + (c * 4))) {
        if (data[r + 3] > 0) {
            firstX = c;
        }
    }
}
for(var c=0;c

这似乎不太正确。我一直坚持这个,你可以看到它应该返回10,因为这是从左边开始的第一列,但它正在向日志中写入99。感觉我是如此接近

就像@bobbybee正确指出的那样,循环的步骤是
4*image\u width

for (var r = 0; r <= data.length; r += (4 * width)) {
    for (var c = 0; c < canvasHeight; c++) {
        if (data[r + 3] > 0) {

        }
    }
}
for(var r=0;r 0){
}
}
}

就像@bobbybee正确指出的那样,循环的步骤是
4*image\u width

for (var r = 0; r <= data.length; r += (4 * width)) {
    for (var c = 0; c < canvasHeight; c++) {
        if (data[r + 3] > 0) {

        }
    }
}
for(var r=0;r 0){
}
}
}

这可以通过单个循环完成(无需在此处嵌套循环):

for(变量y=0;y0){/*…*/}
}
或者挤出一点速度:

var y=0,
length=data.length,///缓存长度
宽度=画布宽度*4;//缓存宽度
while(y0){/*…*/}
y+=宽度;
}

这可以通过单个循环完成(无需在此处嵌套循环):

for(变量y=0;y0){/*…*/}
}
或者挤出一点速度:

var y=0,
length=data.length,///缓存长度
宽度=画布宽度*4;//缓存宽度
while(y0){/*…*/}
y+=宽度;
}

您可以在一个循环中完成所有操作,而无需进行嵌套

var minX = canvas.width,
    minY = canvas.height;

for (var p = 0; p <= data.length; p += 4) {
     var curX = (p / 4) % canvas.width,
         curY = ((p / 4) - curX) / canvas.width;

    /* if what we're checking is higher than our recorded minX and 
      minY skip to the next row */

    if(curX > minX && curY > minY){
        // if minY is greater than 0 continue, if its 0 it can be no less so break.
        if(minY > 0){
            p=(curY+1)*(canvas.width*4); 
        }else{
            break;
        }
    }

    if (data[p + 3] > 0) {
        if (curX < minX) {
            minX = curX;
        };

        if (curY < minY) {
            minY = curY;
        };
    }
}
for (var x = 0; x <= canvas.width; x++) {
    for (var y = 0; y <= canvas.height; y++) {
        if (data[((y * canvas.width + x) * 4) + 3] > 0) {
            if (x < firstX) {
                firstX = x;
            }
            if (y < firstY) {
                firstY = y;
            }

            if (x > lastX) {
                lastX = x;
            }
            if (y > lastY) {
                lastY = y;
            }
        }
    }
}
在我们的例子中,因为我们使用的是分为4个分量值(r/g/b/alpha)的像素数据,所以我们需要将索引除以4,就像我在上面的演示中所做的那样

接下来,我使用
minX
minY
设置画布的宽度和高度。每当我们点击一个像素时,我们检查它的
x
y
是否低于我们存储的最低
x
y
。如果它们较低,则我们保留该值并继续

但是,它更容易读取,并且使用多个循环读取数据

for (var x = 0; x <= canvas.width; x++) {
  for (var y = 0; y <= canvas.height; y++) {
    if (minY < y) {
      break;
    }
    if (data[((y * canvas.width + x) * 4) + 3] > 0) {
      if (x < minX) {
        minX = x;
      }
      if (y < minY) {
        minY = y;
      }
    }
  }
}
for(变量x=0;x lastY){
lastY=y;
}
}
}
}

您可以在一个循环中完成所有操作,而无需进行嵌套

var minX = canvas.width,
    minY = canvas.height;

for (var p = 0; p <= data.length; p += 4) {
     var curX = (p / 4) % canvas.width,
         curY = ((p / 4) - curX) / canvas.width;

    /* if what we're checking is higher than our recorded minX and 
      minY skip to the next row */

    if(curX > minX && curY > minY){
        // if minY is greater than 0 continue, if its 0 it can be no less so break.
        if(minY > 0){
            p=(curY+1)*(canvas.width*4); 
        }else{
            break;
        }
    }

    if (data[p + 3] > 0) {
        if (curX < minX) {
            minX = curX;
        };

        if (curY < minY) {
            minY = curY;
        };
    }
}
for (var x = 0; x <= canvas.width; x++) {
    for (var y = 0; y <= canvas.height; y++) {
        if (data[((y * canvas.width + x) * 4) + 3] > 0) {
            if (x < firstX) {
                firstX = x;
            }
            if (y < firstY) {
                firstY = y;
            }

            if (x > lastX) {
                lastX = x;
            }
            if (y > lastY) {
                lastY = y;
            }
        }
    }
}
在我们的例子中,因为我们使用的是分为4个分量值(r/g/b/alpha)的像素数据,所以我们需要将索引除以4,就像我在上面的演示中所做的那样

接下来,我使用
minX
minY
设置画布的宽度和高度。每当我们点击一个像素时,我们检查它的
x
y
是否低于我们存储的最低
x
y
。如果它们较低,则我们保留该值并继续

但是,它更容易读取,并且使用多个循环读取数据

for (var x = 0; x <= canvas.width; x++) {
  for (var y = 0; y <= canvas.height; y++) {
    if (minY < y) {
      break;
    }
    if (data[((y * canvas.width + x) * 4) + 3] > 0) {
      if (x < minX) {
        minX = x;
      }
      if (y < minY) {
        minY = y;
      }
    }
  }
}
for(变量x=0;x lastY){
lastY=y;
}
}
}
}

不是每次添加4个,而是添加4*宽度。然后在每个垂直列的循环中使用它。不是每次添加4,而是添加4*宽度。然后在每个垂直列的循环中使用它。这种方法似乎不起作用。在每次迭代中,你只得到一个非常小的像素样本,因为
canvas.width*4
将是一个相当大的数字。这种方法只在第一列中获得像素,我想,请参见我的编辑。@domisher这是个想法,但我意识到我误解了迭代的垂直部分(我不知怎么读到了第一条垂直线)这个方法似乎不起作用。在每次迭代中,你只得到一个非常小的像素样本,因为
canvas.width*4
将是一个相当大的数字。这种方法只在第一列中获得像素,我想,请参见我的编辑。@domisher这是个想法,但我意识到我误解了迭代的垂直部分(我不知怎么读到了第一条垂直线):-SI最初确实使用了此方法。问题是,它仍然在一行一行地向下移动,因此尽管Y位置肯定是正确的,但X位置只有在画布上的图像是正方形时才是正确的。查看我更新的小提琴:。您可以看到,第一列的左边有一个彩色像素,实际上是0,但是没有被拾取。@dormisher所以如果我理解正确,您希望第一列和第一行数据出现,但是列和行彼此独立吗?或者在您的数据中,第一列是否优先于第一行?无论如何,我更新了我的答案。如果我很接近,请告诉我。是的,彼此独立。基本上只是“这是从左到右的第一列