2015-01-10 2 views
-1

를 해결합니다. 그래서 DataView와 ArrayBuffer를 사용해야한다고 들었습니다. 이것은 내 시도였습니다 :변환 32BitPackedARGB 배열은 내가 여기에이 코드를 Endiness

var can = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas'); 
can.width = '16'; 
can.height = '16'; 
var ctx = can.getContext('2d'); 
ctx.fillStyle = "rgb(255,0,0)"; 
ctx.fillRect(0, 0, 16, 16); 

// Getting pixels as a byte (uint8) array 
var imageData = ctx.getImageData(0, 0, can.width, can.height); 
var pixels8BitsRGBA = imageData.data; 
console.log(pixels8BitsRGBA.length) 

var sizeOfEachStoredNumber = 4; //bytes 
var numberOfStoresPerPixel = 4; //we have a r g and b 
var numberOfPixels = can.width * can.height; 
var buffer = new ArrayBuffer((numberOfPixels * (sizeOfEachStoredNumber * numberOfStoresPerPixel)) + 8); // +8 bytes for the two leading 32 bytes integers 
console.log((numberOfPixels * (sizeOfEachStoredNumber * numberOfStoresPerPixel)) + 8); 

//buffer size is: 256 repetitions of 4 numbers. each number is 4bytes. so 16 bytes per repetition. 256 reps. so 4096 total bytes is size 
// Reverting bytes from RGBA to ARGB 
//var pixels8BitsARGB = 
var view = new DataView(buffer, 0); 
view.setUint8(0, can.width, true); 
view.setUint8(4, can.height, true); 
for(var i = 0 ; i < pixels8BitsRGBA.length ; i += 4) { 
    var bytePos = i/4*16+8; //starting byte position of this group of 4 numbers // +8 bytes for the two leading 32 bytes integers 
    //console.log(bytePos, h) 
    var r = pixels8BitsRGBA[i ]; 
    var g = pixels8BitsRGBA[i+1]; 
    var b = pixels8BitsRGBA[i+2]; 
    var a = pixels8BitsRGBA[i+3]; 

    view.setUint8(bytePos, a, true); 
    view.setUint8(bytePos+4, r, true); 
    view.setUint8(bytePos+8, g, true); 
    view.setUint8(bytePos+12, b, true); 
} 

// Converting array buffer to a uint32 one, and adding leading width and height 
var pixelsAs32Bits = new Uint32Array(buffer); 

console.log(pixelsAs32Bits); 

두 가지 모두 복사 할 수있는 코드이며 첫 번째 문자는 매우 다른 숫자를 갖습니다. 코드를 수정하려면 어떻게해야합니까? DataView와 ArrayBuffer에는별로 좋지 않습니다.

+0

가능한 복제본 [Get 32Bit Packed ARGB Array 데이터를 html5 캔버스에서 가져 오기] (http://stackoverflow.com/questions/27874550/get-32bit-packed-argb-array-data-from-html5-canvas) –

+0

I 삭제 표시했습니다. 그냥 지워 줬어, 스테판 고마워! – Noitidart

+0

대단히 고맙습니다, 내 정답을 삭제 해 주셔서 감사합니다. -/ –

답변

1

입력 된 배열이 실제로 필요하지는 않지만 사용하는 것이 좋습니다.

첫 조각에 입력 배열없이

ARGBpixmap.push(r + g + b); 

바로이 형태

00000000 RRRRRRRR의 단일 32 비트 정수로 3 바이트로 변환

ARGBpixmap.push((r << 16) + (g << 8) + b); 

할 필요가 GGGGGGGG BBBBBBBBB

대신 1 또는 알파 값을 원할 수 있습니다. 당신이 데이터로 무엇을 할 것인지에 따라 0의 알파 값을 얻기 위해 사용

var r = image_data.data[i]; 
var g = image_data.data[i + 1]; 
var b = image_data.data[i + 2]; 
var a = image_data.data[i + 3]; 
ARGBpixmap.push((a << 24) + (r << 16) + (g << 8) + b); 

참조이 줄을 사용하여 부호없는 수를 얻을 수있을 수 있지만 낮은 32 비트가 정확히 동일로, 정말 문제가 안 http://www.codeonastick.com/2013/06/javascript-convert-signed-integer-to.html

ARGBpixmap.push(((a << 24) + (r << 16) + (g << 8) + b) >>> 0); 
두 번째 조각에서

view.setUint8(bytePos, a, true); 
view.setUint8(bytePos+4, r, true); 
view.setUint8(bytePos+8, g, true); 
view.setUint8(bytePos+12, b, true); 

아마해야

view.setUint8(i + 3, a, true); 
view.setUint8(i + 2, r, true); 
view.setUint8(i + 1, g, true); 
view.setUint8(i + 0, b, true); 

이제는 원본 및 대상에서 바이트 단위로 ARGB 데이터를 처리하기 때문입니다. 나는 이미 바이트 위치이고, 다른 것을 계산할 필요가 없습니다. 관련 차이점은 각 4 바이트 그룹 내에서만 있습니다.

EDIT : 엔디안을 고려하십시오.

+0

그러나 bytePos는 그룹의 시작 바이트 번호를 보유합니다. 따라서 8시에 시작하여 4100에서 끝납니다. – Noitidart

+0

이 경우에는 bytePos가 필요하지 않습니다. (accordedly 편집 됨) –

+0

대단히 감사합니다. 만약''''Array '[16,16, -65536, -65536, -65536, -65536, -65536, -65536, ...] 배열을 얻으면'-65536'은 확실히 틀렸어, 서명하지 않아도 돼? 고마워요. – Noitidart