이미지 처리, 오디오 조작, 네트워크 프로토콜, WebGL 같은 저수준 작업에서는 바이너리 데이터를 직접 다뤄야 합니다. ArrayBuffer와 TypedArray는 자바스크립트에서 바이너리를 효율적으로 처리하는 핵심 API입니다.

ArrayBuffer — 고정 크기 바이너리 버퍼

JS
// 16바이트 버퍼 생성
const buffer = new ArrayBuffer(16);
console.log(buffer.byteLength); // 16

// ArrayBuffer를 직접 읽거나 쓸 수 없음!
// TypedArray나 DataView를 통해 접근해야 함

TypedArray — 버퍼에 타입 뷰 씌우기

JS
const buffer = new ArrayBuffer(16);

// 같은 버퍼에 다른 뷰
const int32View = new Int32Array(buffer);
console.log(int32View.length); // 4 (16바이트 / 4바이트)

const uint8View = new Uint8Array(buffer);
console.log(uint8View.length); // 16 (16바이트 / 1바이트)

// 쓰기
int32View[0] = 42;
console.log(uint8View[0]); // 42 — 같은 메모리를 공유

// 직접 생성 (내부적으로 ArrayBuffer 자동 생성)
const arr = new Float64Array([1.1, 2.2, 3.3]);
console.log(arr.buffer.byteLength); // 24 (8바이트 * 3)

TypedArray 종류

타입크기범위
Int8Array1바이트-128 ~ 127
Uint8Array1바이트0 ~ 255
Uint8ClampedArray1바이트0 ~ 255 (클램핑)
Int16Array2바이트-32768 ~ 32767
Uint16Array2바이트0 ~ 65535
Int32Array4바이트-2^31 ~ 2^31-1
Uint32Array4바이트0 ~ 2^32-1
Float32Array4바이트단정밀도 부동소수점
Float64Array8바이트배정밀도 부동소수점
BigInt64Array8바이트BigInt
BigUint64Array8바이트BigInt (양수)

DataView — 혼합 타입 접근

JS
const buffer = new ArrayBuffer(12);
const view = new DataView(buffer);

// 다른 타입의 데이터를 하나의 버퍼에 저장
view.setUint32(0, 1234);          // 오프셋 0: 32비트 정수
view.setFloat32(4, 3.14);         // 오프셋 4: 32비트 실수
view.setUint16(8, 256);           // 오프셋 8: 16비트 정수
view.setUint16(10, 512, true);    // 리틀엔디안

console.log(view.getUint32(0));     // 1234
console.log(view.getFloat32(4));    // 3.140000104904175

실전 — 이미지 픽셀 조작

JS
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const pixels = imageData.data; // Uint8ClampedArray

// 그레이스케일 변환
for (let i = 0; i < pixels.length; i += 4) {
  const r = pixels[i];
  const g = pixels[i + 1];
  const b = pixels[i + 2];
  const gray = (r + g + b) / 3;
  pixels[i] = pixels[i + 1] = pixels[i + 2] = gray;
  // pixels[i + 3]은 알파(투명도) — 유지
}

ctx.putImageData(imageData, 0, 0);

실전 — fetch로 바이너리 다운로드

JS
async function downloadBinary(url) {
  const response = await fetch(url);
  const buffer = await response.arrayBuffer();
  return new Uint8Array(buffer);
}

// WAV 파일 헤더 파싱 예시
async function parseWavHeader(url) {
  const data = await downloadBinary(url);
  const view = new DataView(data.buffer);

  return {
    chunkId: String.fromCharCode(...data.slice(0, 4)),
    fileSize: view.getUint32(4, true),
    format: String.fromCharCode(...data.slice(8, 12)),
    sampleRate: view.getUint32(24, true),
    bitsPerSample: view.getUint16(34, true),
  };
}

TypedArray와 일반 Array 차이

JS
const typed = new Int32Array([1, 2, 3]);
const normal = [1, 2, 3];

// 타입 강제
typed[0] = 3.14;
console.log(typed[0]); // 3 (정수로 잘림)

// 길이 고정
// typed.push(4); // TypeError — 크기 변경 불가

// 배열 메서드 일부 사용 가능
typed.map((x) => x * 2);     // Int32Array [2, 4, 6]
typed.filter((x) => x > 1);  // Int32Array [2, 3]
typed.find((x) => x === 2);  // 2

// 성능: TypedArray가 대량 숫자 처리에 훨씬 빠름

변환

JS
// TypedArray → 일반 Array
const typed = new Uint8Array([1, 2, 3]);
const arr = Array.from(typed);
const arr2 = [...typed];

// 일반 Array → TypedArray
const typed2 = new Float64Array([1.1, 2.2, 3.3]);

// TypedArray → ArrayBuffer
const buffer = typed.buffer;

// 문자열 → ArrayBuffer (TextEncoder)
const encoder = new TextEncoder();
const encoded = encoder.encode("안녕하세요");
console.log(encoded); // Uint8Array

// ArrayBuffer → 문자열 (TextDecoder)
const decoder = new TextDecoder("utf-8");
const decoded = decoder.decode(encoded);
console.log(decoded); // "안녕하세요"

**기억하기 **: ArrayBuffer는 바이너리 데이터의 컨테이너이고, TypedArray는 특정 숫자 타입으로 읽고 쓰는 "뷰"입니다. 이미지/오디오/네트워크 프로토콜 같은 저수준 작업에서 사용되고, Web Worker의 Transferable Objects와 함께 쓰면 대용량 데이터를 효율적으로 전달할 수 있습니다.

댓글 로딩 중...