代码之家  ›  专栏  ›  技术社区  ›  Liam

从HTML画布获取像素?

  •  95
  • Liam  · 技术社区  · 15 年前

    是否可以查询HTML画布对象以获取特定位置的颜色?

    10 回复  |  直到 6 年前
        1
  •  151
  •   Georg Schölly Crazy Developer    15 年前

    有一个关于 pixel manipulation 在W3C文档中。

    这里是 an example on how to invert an image :

    // Get the CanvasPixelArray from the given coordinates and dimensions.
    var imgd = context.getImageData(x, y, width, height);
    var pix = imgd.data;
    
    // Loop over each pixel and invert the color.
    for (var i = 0, n = pix.length; i < n; i += 4) {
        pix[i  ] = 255 - pix[i  ]; // red
        pix[i+1] = 255 - pix[i+1]; // green
        pix[i+2] = 255 - pix[i+2]; // blue
        // i+3 is alpha (the fourth element)
    }
    
    // Draw the ImageData at the given (x,y) coordinates.
    context.putImageData(imgd, x, y);
    
        2
  •  47
  •   Theo.T    11 年前

    您尝试过GetImageData方法吗?

    data = context.getImageData(x, y, 1, 1).data;
    color = new Color([data[0], data[1], data[2]]);
    
        3
  •  8
  •   Annika Backstrom    15 年前

    是的,请查看getImageData()。下面是一个使用画布的javascript打破验证码的示例:

    http://ejohn.org/blog/ocr-and-neural-nets-in-javascript/

        4
  •  8
  •   Community PPrice    7 年前

    是的,当然,只要你有它的背景。 How to get canvas context?

    var imgData = context.getImageData(0,0,canvas.width,canvas.height);
    // array [r,g,b,a,r,g,b,a,r,g,..]
    
    function getPixel(imgData, index) {
      var i = index*4, d = imgData.data;
      return [d[i],d[i+1],d[i+2],d[i+3]] // returns array [R,G,B,A]
    }
    
    // AND/OR
    
    function getPixelXY(imgData, x, y) {
      return getPixel(imgData, y*imgData.width+x);
    }
    
        5
  •  8
  •   anton-tchekov    9 年前
    function GetPixel(x, y)
    {
        var p = ctx.getImageData(x, y, 1, 1).data; 
        var hex = "#" + ("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6);  
        return hex;
    }
    
    function rgbToHex(r, g, b) {
        if (r > 255 || g > 255 || b > 255)
            throw "Invalid color component";
        return ((r << 16) | (g << 8) | b).toString(16);
    }
    
        6
  •  5
  •   Don Park    14 年前

    请注意,GetImageData返回快照。影响包括:

    • 更改在随后的PutimageData之前不会生效
    • GetImageData和PutImageData调用相对较慢
        7
  •  4
  •   Foreever    10 年前
    // Get pixel data 
    var imageData = context.getImageData(x, y, width, height);
    //color at (x,y) position
    var color = [];
    color['red'] = imageData.data[((y*(imageData.width*4)) + (x*4)) + 0];
    color['green'] = imageData.data[((y*(imageData.width*4)) + (x*4)) + 1];
    color['blue'] = imageData.data[((y*(imageData.width*4)) + (x*4)) + 2];
    color['alpha'] = imageData.data[((y*(imageData.width*4)) + (x*4)) + 3];
    
        8
  •  0
  •   user2226755    6 年前

    你可以使用 i << 2 .

    const data = context.getImageData(x, y, width, height).data;
    const pixels = [];
    
    for (let i = 0, dx = 0; dx < data.length; i++, dx = i << 2) {
        pixels.push({
            r: data[dx  ],
            g: data[dx+1],
            b: data[dx+2],
            a: data[dx+3]
        });
    }
    
        9
  •  0
  •   MD Rijwan    6 年前

    如果要通过将像素坐标传递到函数中来提取像素的特定颜色,这将非常方便

    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext("2d");
    function detectColor(x,y){
    data=ctx.getImageData(x,y,1,1).data;
    col={
    r:data[0],
    g:data[1],
    b:data[2]
    };
    return col;
    }
    

    x,y是要过滤掉颜色的坐标。

    var color=detectColor(x,y)
    

    颜色是对象,你将按颜色得到RGB值。r,color.g,color.b。

        10
  •  0
  •   Kamil Kiełczewski    6 年前

    方便的长读像素一行(绘制像素 here )

    let rp=((s='.myCanvas',c=document.querySelector(s),ctx=c.getContext('2d')) => (x,y)=>Object.values(ctx.getImageData(x, y, 1, 1).data))();
    
    rp(10,20) // rp(x,y) returns: [r,g,b,a] with values 0-255
    

    let rp=((s='.myCanvas',c=document.querySelector(s),ctx=c.getContext('2d')) => (x,y)=>Object.values(ctx.getImageData(x, y, 1, 1).data))();
    
    let pp= ((s='.myCanvas',c=document.querySelector(s),ctx=c.getContext('2d'),id=ctx.createImageData(1,1)) => (x,y,r=0,g=0,b=0,a=255)=>(id.data.set([r,g,b,a]),ctx.putImageData(id, x, y),c))()
    
    // draw point
    pp(50,60,  198,236,247,250) // x,y,  r,g,b,a
    
    // read color
    let c = rp(50,60);
    
    console.log(c);
    <canvas class="myCanvas" width=100 height=100 style="background: black"></canvas>

    第一行是初始部分,您可以在其中更改画布选择器 s='.myCanvas' . 这种简便的一行程序对于测试算法或概念验证很好,但是对于生产代码,最好使用其他更清晰易读的代码。