javascript - 循环直到在 Canvas 中找到一些具有相同颜色的像素

标签 javascript css html canvas

我正在尝试在 Canvas 上找到红色,例如,假设我在 Canvas 上画了一个正方形,所以我想知道如何循环遍历该正方形,当我检测到它时得到 x从现在开始我有这个:

var imgData = context.getImageData(face.x-1, face.y-1, 15+2, 15+2);
var pixels = imgData.data;

for (var i = 0; n = pixels.length, i < n; i += 4) {
    var red = pixels[i];
    var green = pixels[i+1];
    var blue = pixels[i+2];
    var alpha = pixels[i+3];
    //red color
    if(red == 255 && green == 0 && blue == 0){
         //fired when color is red
    }

注意:face.x和face.y是定位图像的X和Y

如何循环正方形,假设它是全黑的,但有 5 个像素是红色的,我想检测它在哪里,并从 Canvas 中的图像中获取 X 和 Y

这是我的Jsfiddle (我试图在 Canvas 上找到红色,例如,假设我在 Canvas 上画了一个正方形,所以我想知道如何循环遍历该正方形,当我检测到它时得到 x 和 y从现在开始我有这个:

var imgData = context.getImageData(face.x-1, face.y-1, 15+2, 15+2);
var pixels = imgData.data;

for (var i = 0; n = pixels.length, i < n; i += 4) {
    var red = pixels[i];
    var green = pixels[i+1];
    var blue = pixels[i+2];
    var alpha = pixels[i+3];
    //red color
    if(red == 255 && green == 0 && blue == 0){
         //fired when color is red
    }

注意:face.x和face.y是定位图像的X和Y

如何循环正方形,假设它是全黑的,但有 5 个像素是红色的,我想检测它在哪里,并从 Canvas 中的图像中获取 X 和 Y

我把这个放了

img.src = "https://i.imgur.com/x9uJH7a.gif";
imgCara.src = "https://i.imgur.com/vJJlYw2.png";

但这只是一个测试,向您展示我正在尝试做什么(这些 img 是我在我的元素中使用的),但我在 jsfiddle 上看不到它......

我尝试用

定位
var w = cara.x-1 + ((i / 4) % (imgData.width));
var z = cara.y-1 + Math.floor((i /4)/(imgData.width));

但是不起作用。

编辑

我遇到了这个问题...

我创建它是为了保存 x 和 y:

var xy={x:2,y:2};

然后我调整了你的循环:

function findMatchingXY(R,G,B,tolerance){
// get the pixel data of the canvas
var data=context.getImageData(0,0,img.width,img.height).data;
// loop through all pixels
for(var y=0;y<img.width;y++){
    for(var x=0;x<img.height;x++){
        // find the pixel data from the data[] rgba array
        //     representing the pixel at [x,y]
        var n=(y*img.width+x)*4;
        // compare this pixel's color channels with the targets
        var matchesRedTarget=Math.abs(R-data[n])<tolerance;
        var matchesGreenTarget=Math.abs(G-data[n+1])<tolerance;
        var matchesBlueTarget=Math.abs(B-data[n+2])<tolerance;
        // does this pixel match the target
        if(data[n+3]>30 && matchesRedTarget
            && matchesGreenTarget && matchesBlueTarget){
            // return the x,y of the first matching pixel
            return({x:x,y:y});
        }
    }}
// no matching pixels found, return null
return(null);
}

在 Chrome 中它说:

maze.js:26 Uncaught TypeError: Cannot read property 'x' of null

最佳答案

由于我只有 51% 确定我理解您的问题,因此我将保留此示例代码,希望它可以帮助您回答或澄清您的问题。代码的关键部分是 findMatchingXY 函数——我对其进行了注释以展示其工作原理。

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

var size=15;
var $xy=$('#xy');
var targetRed=255;
var targetGreen=255;
var targetBlue=187;
var tolerance=5;

ctx.fillStyle='black';
ctx.fillRect(0,0,cw,ch);

$('#place').on('click',function(){
    // calc a random x,y and draw a 15x15 rect there
    var x=Math.random()*(cw-size);
    var y=Math.random()*(ch-size);
    ctx.fillStyle='black';
    ctx.fillRect(0,0,cw,ch);
    ctx.fillStyle='rgb('+targetRed+','+targetGreen+','+targetBlue+')';
    ctx.fillRect(x,y,15,15);
});

$('#find').on('click',function(){
    var xy=findMatchingXY();
    if(xy){
        $xy.text('Found the matching rect at x='+xy.x+', y='+xy.y);
    }else{
        $xy.text('There is no matching rect');
    }
});

$('#place').trigger('click');


function findMatchingXY(){
    // get the pixel data of the canvas
    var data=ctx.getImageData(0,0,cw,ch).data;
    // loop through all pixels
    for(var y=0;y<ch;y++){
    for(var x=0;x<cw;x++){
        // find the pixel data from the data[] rgba array
        //     representing the pixel at [x,y]
        var n=(y*cw+x)*4;
        // compare this pixel's color channels with the targets
        var matchesRedTarget=Math.abs(targetRed-data[n])<tolerance;
        var matchesGreenTarget=Math.abs(targetGreen-data[n+1])<tolerance;
        var matchesBlueTarget=Math.abs(targetBlue-data[n+2])<tolerance;
        // does this pixel match the target
        if(data[n+3]>30 && matchesRedTarget 
                && matchesGreenTarget && matchesBlueTarget){
            // return the x,y of the first matching pixel
            return({x:x,y:y});
        }
    }}
    // no matching pixels found, return null
    return(null);
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<button id='place'>Randomly place a rect</button>
<button id='find'>Find the randomly placed rect</button><br>
<h4 id='xy'>Place a target-color rect then find it.</h4>
<canvas id="canvas" width=300 height=100></canvas>

[添加:使用迷宫图像的示例]

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

var $xy=$('#xy');
var img=new Image();
img.crossOrigin='anonymous';
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/mazeRed.png";
function start(){
    cw=canvas.width=img.width;
    ch=canvas.height=img.height;
    ctx.drawImage(img,0,0);
    var xy=findMatchingXY(255,47,47,10);
    if(xy){
        $xy.text('Found the matching pixel at x='+xy.x+', y='+xy.y);
    }else{
        $xy.text('There is no matching pixel');
    }    
}


function findMatchingXY(targetRed,targetGreen,targetBlue,tolerance){
    // get the pixel data of the canvas
    var data=ctx.getImageData(0,0,cw,ch).data;
    // loop through all pixels
    for(var y=0;y<ch;y++){
    for(var x=0;x<cw;x++){
        // find the pixel data from the data[] rgba array
        //     representing the pixel at [x,y]
        var n=(y*cw+x)*4;
        // compare this pixel's color channels with the targets
        var matchesRedTarget=Math.abs(targetRed-data[n])<tolerance;
        var matchesGreenTarget=Math.abs(targetGreen-data[n+1])<tolerance;
        var matchesBlueTarget=Math.abs(targetBlue-data[n+2])<tolerance;
        // does this pixel match the target
        if(data[n+3]>30 && matchesRedTarget 
                && matchesGreenTarget && matchesBlueTarget){
            // return the x,y of the first matching pixel
            return({x:x,y:y});
        }
    }}
    // no matching pixels found, return null
    return(null);
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4 id='xy'>Finding red line in maze</h4><br>
<canvas id="canvas" width=300 height=100></canvas>

关于javascript - 循环直到在 Canvas 中找到一些具有相同颜色的像素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37030308/

相关文章:

javascript - 类似 Facebook 的开源聊天(使用 Jabber 或 IRC)

javascript - 当你有 ajax 和 css 时如何包含 javascript?

css - 垂直菜单响应

javascript - 通过隐藏/显示重新定位 iframe

html - Border-radius 没有显示在我的电子邮件表上

javascript - jquery 中的 on() 函数不起作用

javascript - 使用 window.scrollY 获取元素 ID 的滚动位置

css - 我可以使用彩色方 block 作为链接而不是使用 CSS 的文本吗?

html - CSS 导航栏着色问题

javascript - fullPage.js 仅显示第一页 - 隐藏除第一页之外的所有页面。为什么?