이미지에서 픽셀의 x, y 좌표 색상을 얻는 방법은 무엇입니까?


답변:


199

Jeff의 답변을 바탕으로 첫 번째 단계는 PNG의 캔버스 표현을 만드는 것입니다. 다음은 이미지와 너비와 높이가 같고 이미지가 그려진 오프 스크린 캔버스를 만듭니다.

var img = document.getElementById('my-image');
var canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);

그 후, 사용자가 클릭, 사용 때 event.offsetX와는 event.offsetY위치를 얻을 수 있습니다. 그런 다음 픽셀을 획득하는 데 사용할 수 있습니다.

var pixelData = canvas.getContext('2d').getImageData(event.offsetX, event.offsetY, 1, 1).data;

하나의 픽셀 만 잡기 때문에 pixelData는 픽셀의 R, G, B 및 A 값을 포함하는 4 개의 항목 배열입니다. 알파의 경우 255보다 작은 것은 어느 정도의 투명도를 나타내며 0은 완전히 투명합니다.

다음은 jsFiddle 예제입니다. http://jsfiddle.net/thirtydot/9SEMf/869/ 이 모든 작업에서 편의를 위해 jQuery를 사용했지만 반드시 필요한 것은 아닙니다.

참고 : getImageData 데이터 유출을 방지하기 위해 브라우저의 동일 출처 정책에 해당합니다. 즉, 다른 도메인의 이미지로 캔버스를 더 럽히거나 (내 생각에는 일부 브라우저에서이 문제를 해결했을 수 있습니다) 모든 도메인의 SVG를 사용하면이 기술이 실패합니다. 이렇게하면 사이트에서 로그인 한 사용자를 위해 사용자 지정 이미지 자산을 제공하고 공격자가 이미지를 읽고 정보를 얻으려는 경우를 방지 할 수 있습니다. 동일한 서버에서 이미지를 제공하거나 교차 출처 리소스 공유를 구현하여 문제를 해결할 수 있습니다 .


3
붐-굉장한 직업. 나는 이렇게 바이올린을 만들어야한다는 것을 알았지 만 너무 뚱뚱하고 게으르다. 당신은 여기를 살해
제프 에스 칼란에게

이것이 정확하려면 캔버스의 좌표 공간을 설정해야합니다. 즉, 이미지 치수와 일치하도록 너비와 높이를 설정해야합니다. CSS 너비와 높이는 레이아웃을위한 최종 캔버스를 늘리는 역할 만하므로 표시되지 않은 요소 일 때는 도움이되지 않습니다. $ ( '<canvas width ='+ img.width + 'height ='+ img.height + '/>');와 같은 것을 시도하십시오. 아니면 오프 스크린 캔버스에는 적용되지 않습니까?
fabspro dec.

@fabspro : 아주 좋은 점입니다. 이미지 데이터를 그리고 읽는 것은 컨텍스트를 통해 이루어지기 때문에 너비와 높이 값은 의미가 없습니다. 컨텍스트가 아닌 캔버스가 왜곡되어 있고 내 데모에서이 효과를 보지 못한 이유는 단순히 이미지가 컨텍스트의 초기 너비 / 높이보다 작기 때문입니다. 이 액세스 안전하지만 나는 그에 따라 업데이트 할 것입니다 .width.height연결을 통해보다 캔버스 자체에.
Brian Nickel


6
원격 이미지에는 이것을 사용할 수 없습니다. "캔버스가 출처 간 데이터로 오염 되었기 때문에 캔버스에서 이미지 데이터를 가져올 수 없습니다. SecurityError : 사용자 에이전트의 보안 정책을 위반하려고했습니다."
Karl Glaser 2013

18

@pst가 위에서 말했듯이 Canvas는이를 수행하는 좋은 방법입니다. 좋은 예를 보려면이 답변을 확인하십시오.

HTML Canvas에서 getPixel?

특별히 도움이 될 몇 가지 코드 :

var imgd = context.getImageData(x, y, width, height);
var pix = imgd.data;

for (var i = 0, n = pix.length; i < n; i += 4) {
  console.log pix[i+3]
}

이것은 행 단위로 진행되므로 x, y로 변환하고 for 루프를 직접 검사로 변환하거나 내부에서 조건부를 실행해야합니다.

질문을 다시 읽으면 그 사람이 클릭 한 포인트를 얻을 수 있기를 원하는 것 같습니다. 이것은 jquery의 클릭 이벤트로 매우 쉽게 수행 할 수 있습니다. 다음과 같이 클릭 핸들러 내에서 위 코드를 실행하면됩니다.

$('el').click(function(e){
   console.log(e.clientX, e.clientY)
}

x 및 y 값을 가져와야합니다.


이것은 댓글 작성자가 (겉보기에) 질문 한 것이 아니며 질문에 전혀 대답하지 않습니다. 수락 된 답변이 작동합니다. 나는 ...이 답변을 삭제하는 것이 좋습니다
Agamemnus

5

앞의 두 답변은 Canvas 및 ImageData를 사용하는 방법을 보여줍니다. 실행 가능한 예제와 이미지 처리 프레임 워크를 사용하여 답변을 제안하고 싶으므로 픽셀 데이터를 수동으로 처리 할 필요가 없습니다.

MarvinJ 는 x, y 좌표의 픽셀에 대한 투명도 값을 간단히 반환하는 image.getAlphaComponent (x, y) 메서드를 제공합니다 . 이 값이 0이면 픽셀은 완전히 투명하고 1에서 254 사이의 값은 투명도 수준이며 마지막으로 255는 불투명합니다.

시연을 위해 투명한 배경과 (0,0)(150,150) 좌표에 두 픽셀이있는 아래 이미지 (300x300)를 사용했습니다 .

여기에 이미지 설명 입력

콘솔 출력 :

(0,0) : 투명
(150,150) : NOT_TRANSPARENT

image = new MarvinImage();
image.load("https://i.imgur.com/eLZVbQG.png", imageLoaded);

function imageLoaded(){
  console.log("(0,0): "+(image.getAlphaComponent(0,0) > 0 ? "NOT_TRANSPARENT" : "TRANSPARENT"));
  console.log("(150,150): "+(image.getAlphaComponent(150,150) > 0 ? "NOT_TRANSPARENT" : "TRANSPARENT"));
}
<script src="https://www.marvinj.org/releases/marvinj-0.7.js"></script>


2

와 함께 : 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) {
    if (data[dx+3] <= 8)
        console.log("transparent x= " + i);
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.