Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

JavaScript로 PNG 이미지의 투명하지 않은 영역 감지하기

PNG 이미지에서 투명하지 않은 영역을 감지하는 방법

웹 개발을 하다 보면 PNG 이미지의 전체 크기가 아니라, 실제로 픽셀이 그려진 불투명(opaque) 영역의 경계를 알아내야 할 때가 있습니다. 스프라이트 최적화, 이미지 자동 잘라내기(auto-crop), 클릭 판정 등이 대표적인 활용 사례입니다. 이 글에서는 캔버스(Canvas) API를 이용해 투명하지 않은 픽셀의 경계를 찾는 절차를 정리합니다.

핵심 절차 요약

다음 순서대로 처리하면 이미지의 실제 콘텐츠 영역(bounding box)을 구할 수 있습니다.

  1. 픽셀 버퍼 확보 – 이미지를 캔버스에 그린 뒤 getImageData()로 픽셀 데이터를 가져옵니다.
  2. 32비트 정수 배열로 변환Uint32Array 뷰를 만들어 픽셀 하나를 한 번에 읽어 성능을 높입니다.
  3. x1 경계 탐색 – 왼쪽(x = 0)부터 오른쪽으로 스캔하여 처음으로 불투명한 픽셀이 나타나는 열을 찾습니다.
  4. x2 경계 탐색 – 오른쪽(width − 1)부터 왼쪽으로 스캔하여 마지막 불투명 열을 찾습니다.
  5. y1 경계 탐색 – 위쪽(y = 0)부터 아래로 스캔하여 첫 번째 불투명 행을 찾습니다.
  6. y2 경계 탐색 – 아래쪽(height − 1)부터 위로 스캔하여 마지막 불투명 행을 찾습니다.

예제 코드

const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;

const ctx = canvas.getContext('2d', { willReadFrequently: true });
ctx.drawImage(img, 0, 0);

// 픽셀 데이터를 32비트 정수 배열로 참조
const pixels = new Uint32Array(
ctx.getImageData(0, 0, canvas.width, canvas.height).data.buffer
);

const { width, height } = canvas;
let x1 = width, x2 = -1, y1 = height, y2 = -1;

for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
const alpha = pixels[y * width + x] >>> 24; // 상위 8비트 = 알파 값
if (alpha !== 0) { // 투명하지 않은 픽셀 발견
if (x < x1) x1 = x;
if (x > x2) x2 = x;
if (y < y1) y1 = y;
if (y > y2) y2 = y;
}
}
}

if (x2 === -1) {
console.log('완전히 투명한 이미지입니다.');
} else {
console.log(`불투명 영역: (${x1}, ${y1}) ~ (${x2}, ${y2})`);
}

구현 시 주의할 점

  • 엔디안(Endianness): Uint32Array로 읽은 값의 바이트 순서는 플랫폼에 따라 다릅니다. 대부분의 환경(리틀 엔디안)에서는 상위 8비트가 알파 값이지만, 빅 엔디안 환경에서는 하위 8비트가 알파가 되므로 주의해야 합니다.
  • CORS 제약: 외부 도메인의 이미지를 사용하려면 img.crossOrigin = 'anonymous' 설정과 서버 측 CORS 허용이 필요합니다. 그렇지 않으면 캔버스가 오염(tainted)되어 getImageData() 호출 시 보안 예외가 발생합니다.
  • 성능: 픽셀 단위 스캔은 O(width × height) 비용이 듭니다. 해상도가 매우 큰 이미지라면 Web Worker에서 처리하거나, 축소된 이미지로 먼저 근사 영역을 찾은 뒤 원본에서 정밀 스캔하는 방식을 고려하세요.

마무리

이 방식은 이미지의 실제 콘텐츠 영역을 구하는 가장 기본적이면서도 확실한 방법입니다. 게임 스프라이트 충돌 판정, 이미지 자동 트리밍, UI 요소 정렬 등 다양한 곳에 응용할 수 있으니, 프로젝트의 요구 사항에 맞게 최적화하여 활용해 보시기 바랍니다.