2017-01-06 1 views
0

캔버스에서 픽셀 정보를 읽을 수있는 기능이 있습니다. 다음과 같이 보입니다 :ArrayBuffer를 사용하여 캔버스에서 픽셀 정보 가져 오기

function getPx (imageData, x, y) { 

    var r = imageData.data[((y * (imageData.width * 4)) + (x * 4))], 
     g = imageData.data[((y * (imageData.width * 4)) + (x * 4)) + 1], 
     b = imageData.data[((y * (imageData.width * 4)) + (x * 4)) + 2], 
     a = imageData.data[((y * (imageData.width * 4)) + (x * 4)) + 3]; 

    return { 
     r: r, 
     g: g, 
     b: b, 
     a: a, 
     black: (r + g + b)/3 
    }; 

} 

이 작동하지만 약간 느립니다. 이 기사에서 알 수 있듯이 https://hacks.mozilla.org/2011/12/faster-canvas-pixel-manipulation-with-typed-arrays/에는 ArrayBuffer라는 것을 사용하여 canvas에서 imageData를 읽고 쓸 수있는 훨씬 빠른 방법이 있습니다. 나는 불행하게도 이것을 작동시킬 수 없다. 그래서 누구든지 어떻게하는지 알고 있습니까?

UPDATE :

은 내가 몇 가지 포인트 색상이나 알파 값을 측정 할 캔버스, 그래서 나는이 모든 픽셀을하지 않습니다. 나의 시도는 지금까지 다음과 같습니다

function getPx (imageData, x, y) { 

    var data32 = new Uint32Array(imageData.data.buffer); 
    var rv = data32[y * imageData.width + x]; 
    return rv; 

} 

이 값을 반환하고 올바른 방법에있을 것 같다, 그러나 내가 할 값이 4076863488 및 4244635648처럼 보일 수 있으며, 내가 그들을 설정하는 방법을 정말 잘 모르겠어요 내가 쓴 데이터에

+0

arrayBuffer는 전체 imageData를 반복 할 때 실제로 더 빠릅니다. 이미지 데이터에서 4 개의 인덱스를 얻는 것에 대한 개선점을 확신 할 수 없습니다. (모든 픽셀에 대해이 함수를 호출하는 경우를 제외하고!? oO Naah는 그렇지 않습니다.). 그러나 arrayBuffer로 시도한 것을 보여줌으로써 우리가 잘못한 것을 말할 수 있습니다. 그렇지 않으면 우리가 할 수있는 일은 정말로 링크 된 기사를 다시 쓰는 것뿐입니다. – Kaiido

+0

@Kaiido 감사합니다. 다시보세요 – arpo

+1

흠! 32 비트 버퍼 뷰로 처리하려면 각 getPx가 아닌 arrayBuffer를 한 번 선언하십시오. 또한, 당신이 가지고있는 가치는 사람이 읽을 수 있도록 16 진수 문자열로 변환해야합니다 (적어도 나를 ;-)). '.toString (16)'메쏘드를 사용하고 나서 2 개의 문자들을 나누고'parseInt (val, 16)'을 다시 호출하여 base10으로 돌아갈 수 있습니다. 주문은 작은 엔디안에서 a, b, g, r입니다. 따라서 픽셀이'0xfd000000' 또는'rgba (0,0,0,243)'및'0xfd000000' 또는'rgba (0,0,0,253)'라고 말할 수 있습니다. 하지만 우리가 필요한 정확한 값을 추출해내는 것을 모르는 어떤 방법이있을 수 있습니다 ... – Kaiido

답변

0

@Kaiido가 언급했듯이 속도가 느립니다. 그러나 이것에 대해 더 자세히 설명하고 싶은 다른 사람들에게는 나의 마지막 기능이 있습니다.

function getPx (imageData, x, y) { 

    var data32 = new Uint32Array(imageData.data.buffer), 
     val32 = data32[y * imageData.width + x], 
     str32, 
     a = 0, 
     b = 0, 
     g = 0, 
     r = 0; 

    if (val32 > 0) { 
     str32 = val32.toString(16); 
     a = parseInt(str32.substr(0, 2), 16); 
     b = parseInt(str32.substr(2, 2), 16); 
     g = parseInt(str32.substr(4, 2), 16); 
     r = parseInt(str32.substr(6, 2), 16); 
    } 

    return { 
     r: r, 
     g: g, 
     b: b, 
     a: a, 
     black: (r + g + b)/3 
    }; 

} 

또한, 그것은 data32 = 새로운 Uint32Array (imageData.data.buffer) 당신이 기능에 동일한 imageData의 많은 시간을 호출하면 함수의 외부를 넣어하는 것이 좋습니다.

관련 문제