Get a pixel from HTML Canvas?

后端 未结 10 2011
情深已故
情深已故 2020-11-22 12:41

Is it possible to query a HTML Canvas object to get the color at a specific location?

相关标签:
10条回答
  • 2020-11-22 13:45
    function GetPixel(context, x, y)
    {
        var p = context.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);
    }
    
    0 讨论(0)
  • 2020-11-22 13:45

    You can use 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]
        });
    }
    
    0 讨论(0)
  • 2020-11-22 13:46

    Fast and handy

    Use following class which implement fast method described in this article and contains all you need: readPixel, putPixel, get width/height. Class update canvas after calling refresh() method. Example solve simple case of 2d wave equation

    class Screen{
      constructor(canvasSelector) {
        this.canvas = document.querySelector(canvasSelector);
        this.width  = this.canvas.width;
        this.height = this.canvas.height;
        this.ctx = this.canvas.getContext('2d');
        this.imageData = this.ctx.getImageData(0, 0, this.width, this.height);
        this.buf = new ArrayBuffer(this.imageData.data.length);
        this.buf8 = new Uint8ClampedArray(this.buf);
        this.data = new Uint32Array(this.buf);  
      }
      
      // r,g,b,a - red, gren, blue, alpha components in range 0-255
      putPixel(x,y,r,g,b,a=255) {
        this.data[y * this.width + x] = (a << 24) | (b << 16) | (g <<  8) | r;
      }
      
      readPixel(x,y) {
        let p= this.data[y * this.width + x]
        return [p&0xff, p>>8&0xff, p>>16&0xff, p>>>24];
      }
    
      refresh() {
        this.imageData.data.set(this.buf8);
        this.ctx.putImageData(this.imageData, 0, 0);
      }
    }
    
    
    
    
    // --------
    // TEST
    // --------
    
    let s=new Screen('#canvas');
    
    function draw() {
    
      for (var y = 1; y < s.height-1; ++y) {
        for (var x = 1; x < s.width-1; ++x) {      
          let a = [[1,0],[-1,0],[0,1],[0,-1]].reduce((a,[xp,yp])=> 
            a+= s.readPixel(x+xp,y+yp)[0]
          ,0);
          let v=a/2-tmp[x][y];
          tmp[x][y]=v<0 ? 0:v;
        }
      }
    
      for (var y = 1; y < s.height-1; ++y) {
        for (var x = 1; x < s.width-1; ++x) {  
          let v=tmp[x][y];
          tmp[x][y]= s.readPixel(x,y)[0];
          s.putPixel(x,y, v,v,v);
        }
      }
    
      s.refresh();
      window.requestAnimationFrame(draw)
    }
    
    // temporary 2d buffer ()for solving wave equation)
    let tmp = [...Array(s.width)].map(x => Array(s.height).fill(0));
    
    function move(e) { s.putPixel(e.x-10, e.y-10, 255,255,255);}
    
    draw();
    <canvas id="canvas" height="150" width="512" onmousemove="move(event)"></canvas>
    <div>Move mouse on black box</div>

    0 讨论(0)
  • 2020-11-22 13:48

    Yup, check out getImageData(). Here's an example of breaking CAPTCHA with JavaScript using canvas:

    OCR and Neural Nets in JavaScript

    0 讨论(0)
提交回复
热议问题