从HTML5画布垂直迭代像素
Iterating pixels vertically from HTML5 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 y = (r / width) / 4;
heightFirst = y;
break;
}
}
我现在需要垂直地迭代数据。我意识到这可能是使用嵌套的for循环来完成的,并做这样的事情:
for (var r = 0; r <= data.length; r += 4) {
for (var c = 0; c < canvasHeight; c++) {
if (data[(r + 3) + (c * width)] > 0) {
}
}
}
我不确定具体的实现/计算,有人能帮我吗??
编辑
正如@bobbybee和@danielpolencic所提到的,一个增加4*宽度的循环将增加一个垂直列:
for (var r = 0; r <= data.length; r += (4 * width)) {
if (data[r + 3] > 0) {
// do whatever
}
}
然而,这只会获得第一列像素的信息。我想下一步是重复上面的循环,但将其增加列数(由于颜色数据而乘以4),循环如下:
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;
}
}
}
这似乎不太正确。我把这个放在这个小提琴上,正如你所看到的,它应该返回10,因为这是左边的第一列,但它在日志中写99。感觉我离得太近了!
您可以在一个循环中完成所有操作,而无需嵌套。
实时演示
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;
};
}
}
以下是从一维数组中获取x和y的公式
X = Index % Width
Y = (Index - x) / Width
在我们的情况下,由于我们使用的像素数据被分为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;
}
}
}
}
演示以获取lastX和lastY
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;
}
}
}
}
正如@bobbybee正确指出的那样,循环的步骤是4 * image_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 y = 0; y < data.length; y += canvas.width * 4) {
if (data[y + 3] > 0 ) { /*...*/ }
}
或者挤出一点速度:
var y = 0,
length = data.length, /// cache length
width = canvas.width * 4; /// cache width
while(y < length) {
if (data[y + 3] > 0 ) { /*...*/ }
y += width;
}
相关文章:
- 如何在javascript中迭代数字列表
- JS:检查URL中的参数,然后迭代一个参数为var的函数
- 如何迭代Array.prototype函数
- 如何使用jquery迭代具有相同属性的html元素并查找onclick事件
- 在ejs-partial中对JSON对象进行迭代
- 如何在DataTables 2.1中迭代对象数组
- 使用递归属性迭代保留属性结构
- 正在停止.在jquery中的特定时间间隔内,每次迭代的每次执行
- 如果30秒未单击,请应用CSS一次,将其删除,然后重新迭代
- 主干-从模板中迭代的集合中获取特定的模型
- 创建一个方法,通过一个窗口进行迭代并获取Titanium中的所有控件
- 什么's是在javascript中迭代项的最佳方式
- 为什么这只是迭代 HTMLCollection 的奇怪元素
- 是否“;对于的“;循环迭代遵循JavaScript中的数组顺序
- Babel编译错误:找不到模块核心js/library/fn/get迭代器
- 在es6中,将带有回调的事件侦听器设置为可迭代的
- jQuery-迭代不正确?(太长,无法执行)
- 每个$.,循环获胜't逐个迭代HTML元素
- 如何在Jquery中迭代JSON数组
- 从HTML5画布垂直迭代像素