HTML Canvas에서 getPixel?


111

특정 위치의 색상을 얻기 위해 HTML Canvas 객체를 쿼리 할 수 ​​있습니까?

답변:


171

W3C 문서 에 픽셀 조작 에 대한 섹션이 있습니다 .

다음 은 이미지를 반전하는 방법에 대한 예입니다 .

var context = document.getElementById('myCanvas').getContext('2d');

// 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);

픽셀 조작 섹션은 이제 여기에서 사용할 수 있습니다. w3.org/TR/2dcontext2/#pixel-manipulation
jtraulle

55

getImageData 메소드를 사용해 보셨습니까?

var data = context.getImageData(x, y, 1, 1).data;
var rgb = [ data[0], data[1], data[2] ];

2
이것은 canvas.getImageData ()가 아닌 context.getImageData ()가 아니어야합니까?
Crashalot

2
@Crashalot은 var "canvas"에 포함 된 내용에 따라 달라지며, 단순히 엉뚱한 var 이름을 가진 캔버스의 컨텍스트 일 ​​수 있습니다.
tbleckert

1
와우, 매우 우아합니다! 나는 전체 맥락에서 요점을 찾는 것에 대해 생각했지만 이것은 훨씬 더 똑똑합니다.
TheOne 2013-01-08

5
이것은 영리하지만 getPixel을 많이 호출 하려는 경우 전체 이미지 (0,0, width, height)에 대해 ImageData 객체를 캐시 한 다음 Georg의 대답과 같은 방식으로 인덱스를 계산하는 것이 훨씬 빠릅니다 idx = (y * width + x) * 4. 그러나 이미지가 변경 될 때마다 캐시 된 개체를 새로 고치는 것을 잊지 마십시오.
noio

2
Color()생성자는 무엇입니까 ? 그것은 어디에도 존재하지 않는 것 같습니다
fregante 2015-06-30

12

예, 컨텍스트가 있다면 그렇습니다. 캔버스 컨텍스트를 얻는 방법?

var imgData = context.getImageData(0,0,canvas.width,canvas.height);
// { data: [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);
}



추신 : 데이터를 변경하고 캔버스에 다시 그릴 계획이라면 다음을 사용할 수 있습니다.subarray

var
 a = getPixel(idt, 188411), // Array(4) [0, 251, 0, 255]
 b = idt.data.subarray(188411*4, 188411*4 + 4) // Uint8ClampedArray(4) [0, 251, 0, 255]

a[0] = 255 // does nothing
getPixel(idt, 188411), // Array(4) [0, 251, 0, 255]

b[0] = 255 // mutates the original imgData.data
getPixel(idt, 188411), // Array(4) [255, 251, 0, 255]

// or use it in the function
function getPixel(imgData, index) {
  var i = index*4, d = imgData.data;
  return imgData.data.subarray(index, index+4) // returns subarray [R,G,B,A]
}

http://qry.me/xyscope/ 에서 실험 할 수 있습니다 . 코드는 소스에 있습니다. 복사 / 붙여 넣기 만하면됩니다.


2
예이! 덕분에 아주 잘 작동하고 전화를 걸기보다 waay 빠른context.getImageData(x, y, 1, 1);
adelriosantiago

실제로 더 빠릅니다. 감사!
dmitru

9
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);
}

4
ctx는 GetPixel에서 속성으로 설정되어야합니다
Marcio

1
좋은 rgbToHex 반환 성명
Qwerty


6

getImageData는 스냅 샷을 반환합니다. 의미는 다음과 같습니다.

  • 변경 사항은 후속 putImageData까지 적용되지 않습니다.
  • getImageData 및 putImageData 호출은 상대적으로 느립니다.

4
// 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];

0

사용할 수 있습니다 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

편리한 긴 읽기 픽셀 oneliner ( 여기에 픽셀 그리기 )

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

첫 번째 줄은 캔버스 선택기를 변경할 수있는 초기 부분 s='.myCanvas'입니다. 이 편리한 oneliner는 테스트 알고리즘이나 개념 증명에 적합하지만 프로덕션 코드의 경우 더 명확하고 읽기 쉬운 코드를 사용하는 것이 좋습니다.


0

픽셀 좌표를 함수에 전달하여 특정 픽셀 색상을 추출하려는 경우 유용합니다.

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 값을 얻을 것이다 color.r, color.g, color.b.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.