【问题标题】:Any javascript method for canvas image cover detection?任何用于画布图像封面检测的javascript方法?
【发布时间】:2013-09-26 16:47:22
【问题描述】:

我正在开发以下案例。

  1. 由 JS 创建的 HTML 画布。
  2. 画布上有一个星形图像(从 alpha=0 背景的 png 加载)和一个菱形图像(也从 alpha=0 背景的 png 加载)。
  3. 钻石图像正在向星形图像移动。
  4. 当菱形图像完全在星形图像之后,例如只显示星形图像而菱形图像完全在星形图像之后,alert("Hidden");
  5. 如果显示多于一个像素的菱形,则不应出现警报。

由于星星背景的alpha值为0,也就是说星星不是一个矩形,所以很难检测星星图片是否完全覆盖了菱形图片。

是否有任何库或方法来检测图像是否被其他图像完全覆盖?

或者,有没有人知道这个算法的名字,以便我在JS中实现?

感谢您的帮助!

【问题讨论】:

  • 很抱歉,但要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是题外话,因为它们往往会吸引固执己见的答案和垃圾邮件。相反,请描述问题以及迄今为止为解决该问题所做的工作。
  • 只需将画布的内容与仅绘制顶部图像的单独画布进行比较。如果它们包含相同的数据,则只有顶部图像可见
  • @j08691 我将标题从“javascript 库”更改为“javascript 方法”
  • @Ken-AbdiasSoftware 如果有很多图像会不会很慢?有更快的方法吗?
  • 除非您事先知道几何形状并且可以进行路径点检查(或者更确切地说检查两条路径之间的交点),否则没有任何更快的方法。您可以提前跟踪对象并将这些多边形用作路径检查的基础。如果这不是一个选项,您将不得不检查像素。您可以通过仅检查对象的一部分来减少像素检查负载,您知道必须隐藏它才能触发的部分。

标签: javascript html image image-processing canvas


【解决方案1】:

对于形状未知的物体,我们可以通过像素检查来检查物体是否落后。

这是一个完整的例子:

ONLINE DEMO HERE

(GameAlchemist 提供了modified version here

/// basic allocations
var ctx = demo.getContext('2d'),
    os = document.createElement('canvas'),
    octx = os.getContext('2d'),
    w = os.width = demo.width,
    h = os.height = demo.height,

    /// the images
    urlD = 'http://i.imgur.com/U72xIMZ.png',
    urlS = 'http://i.imgur.com/n5rgo11.png',
    imgD = new Image(),
    imgS = new Image(),
    cnt = 2,

    /// check region (optimized)
    rect = [140, 140, 180, 60];

/// load images and when ready, start show    
imgD.crossOrigin = imgS.crossOrigin = 'anonymous';
imgD.onload = imgS.onload = function() {
    cnt--;
    if (cnt === 0) start();
}
imgD.src = urlD;
imgS.src = urlS;

主函数检查上面定义的区域内的像素。为了优化,我们可以缩小搜索范围。如果您需要检查图像是否在其他尺寸上可见,则只需扩展区域以检查该区域。

该函数将屏幕外画布与仅绘制最前面的图像与绘制背景和前景的“实时”画布进行比较。

如果实时画布 = 屏幕外画布,则意味着背景图像不可见。

function start() {

    octx.drawImage(imgS, (w - imgS.width) * 0.5, 20);

    var x = -50,
        buffer1 = octx.getImageData(rect[0], rect[1], rect[2], rect[3]).data,
        len = buffer1.length;

    loop();

    function loop() {
        ctx.clearRect(0, 0, w, h);
        ctx.drawImage(imgD, x, 130);
        ctx.drawImage(imgS, (w - imgS.width) * 0.5, 20);

        if (compare() === true) {
            info.innerHTML = 'Object is behind!';
            return;
        }

        x += 2;
        if (x < w) requestAnimationFrame(loop);
    }

    function compare() {
        var buffer2 = ctx.getImageData(rect[0], rect[1], rect[2], rect[3]).data,
            i = len - 1;

        while(i--) {
            if (buffer1[i] !== buffer2[i]) return false
        }
        return true;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-25
    • 2017-06-20
    • 1970-01-01
    • 2017-09-11
    • 2014-02-28
    • 2014-01-02
    • 1970-01-01
    • 2016-01-26
    相关资源
    最近更新 更多