【问题标题】:canvas getImageData returns too many pixelscanvas getImageData 返回太多像素
【发布时间】:2017-04-09 11:23:09
【问题描述】:

我正在创建一个移动网络应用游戏,让用户在屏幕上滑动以清除它。 我正在尝试编写一个智能函数来检测几乎整个画布何时是透明的。

我有一个间隔每秒调用下面的函数来进行检查。 它应该工作的方式是我取画布的一个 20 像素宽的扇区,与画布一样高。

这个函数运行起来应该很流畅,但是由于某种原因,getImageData 函数返回了很多像素。我的扇区总是 20px 宽并且具有相同的高度,所以它应该每次返回相同数量的像素。当然,由于 getImageData 返回的数字越来越大,我的循环越来越慢。

有人知道这是什么原因吗?我是否误解了 getImageData 函数的工作方式?

isCanvasTransparent: function (fromX, toX, currentIteration) {

        if(currentIteration < this.clearedIterations) { // If a sector is already clear, we dont need to check it again
            this.isCanvasTransparent(fromX + 20, toX + 20, currentIteration + 1);
            return;
        } else {
            var data = this.context.getImageData(fromX, 0, toX, parseInt(this.canvas.style.width)).data;
            var counter = 0;
            var i = 0;

            // For some reason, the length increases, but the diff between fromX and toX is always 20
            console.log(data.length); 

            for(i=0;i<(data.length);i+=4) { 
                if(data[i+3]!==0){
                    counter++;
                    // I stop iterating, since there are too many non transparent pixels
                    if(counter > 10) {
                        break;
                    }
                }
            }

            // I accept that 10 pixels in each sector is not transparent
            if((counter < 10) && !this.alerted) {
                this.clearedIterations++; // Here we increase clearedIterations, since this sector is clear

                // There are no more iterations, so we are done
                if(currentIteration === this.maxIterations) {
                     // this is the interval that calls isCanvasTransparent(0, 20, 0)
                     // in the first place. The interval is called each second. But as soon the whole view
                     // is transparent, we clear it, so that isCanvasTransparent is no longer called
                    clearInterval(this.checkCanvasTimeout);
                    this.alerted = true;
                    TouchHelpers.removeTouchEvents();
                    this.levelCompleted();
                    return;
                } else {
                    // this sector is clear, but we need to check the next one, since we are not at the end
                    this.isCanvasTransparent(fromX + 20, toX + 20, currentIteration + 1);
                }
            }
        }
    },

【问题讨论】:

    标签: javascript canvas getimagedata


    【解决方案1】:

    如果不查看您如何设置 fromX/toX,则无法确定,但您似乎没有为 getImageData 提供正确的参数。

    context.getImageData 有这些参数:

    • x:要提取的起始 x 坐标,
    • y:要提取的起始 y 坐标,
    • 宽度:提取这么多像素宽的块,
    • 高度:提取这么多像素高的块

    [补充:基于附加信息]

    如果您想要大小相等的像素数据块,您的第一个调用是

    var data=getImageData(0,0, 20, canvas.height).data;
    

    你的第二个电话是:

    // Note: the width arguement remains at 20, not increase to 40
    
    var data=getImageData(20,0, 20, canvas.height).data;
    

    【讨论】:

    • 对不起,如果我不清楚。我尝试在您在那里看到的 clearinterval 代码中解释这一点。但无论如何,我最初调用函数的方式是使用这些参数 (0,0, 20, )。然后它下一次递归地向右移动 20 个像素。所以第二次 (20, 0, 40, ) 被调用。
    • 问题出在...您的第二次调用 s/b (20,0,20,canvas.height) -- 第三个宽度参数应保持在 20,而不是增加到 40。干杯!
    • 啊……你说得对!现在我的功能真的很顺利。我不能为此感谢你!真的很感激! :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    • 2018-10-24
    • 1970-01-01
    • 1970-01-01
    • 2018-08-07
    相关资源
    最近更新 更多