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

HTML5에서 '최근접 이웃(Nearest Neighbor)' 리샘플링으로 이미지 크기 조절하는 방법

네, 충분히 가능합니다. HTML5에서 최근접 이웃(nearest neighbor) 방식으로 이미지를 확대·축소하려면 CSS의 image-rendering 속성을 활용하는 방법과, 캔버스(Canvas) API로 픽셀 데이터를 직접 처리하는 방법, 크게 두 가지를 사용할 수 있습니다.

방법 1: CSS의 image-rendering 속성 활용

가장 간단한 방법은 CSS에서 image-rendering 속성을 지정하는 것입니다.

image-rendering: pixelated;                 /* 표준 값 (Chrome, Edge, Firefox 등) */
image-rendering: -webkit-optimize-contrast; /* WebKit 계열 */
image-rendering: -moz-crisp-edges;          /* Firefox */

pixelated는 현재 대부분의 모던 브라우저가 지원하는 표준 값으로, 이미지를 확대할 때 보간(interpolation) 없이 가장 가까운 픽셀의 색상을 그대로 사용합니다. 덕분에 경계가 흐려지지 않고 도트가 또렷하게 유지되므로, 픽셀 아트나 레트로 스타일 그래픽에 특히 적합합니다.

방법 2: Canvas로 픽셀 단위 리샘플링 직접 구현

CSS만으로 해결되지 않는 상황이라면, 오프스크린 캔버스(offscreen canvas)에 원본 이미지를 그린 후 픽셀 데이터를 추출하고, 이를 원하는 배율(zoom)만큼 반복해서 그려주는 방식으로 직접 구현할 수 있습니다.

// 1. 오프스크린 캔버스에 원본 이미지를 그린다
var a = document.createElement('canvas').getContext('2d');
a.drawImage(myImg, 0, 0);

// 2. 픽셀 데이터(RGBA 배열)를 가져온다
var image = a.getImageData(0, 0, myImg.width, myImg.height).data;

// 3. 각 픽셀을 zoom 크기의 사각형으로 확대해 그린다
for (var x = 0; x < myImg.width; ++x) {
    for (var y = 0; y < myImg.height; ++y) {
        var i = (y * myImg.width + x) * 4;
        var r = image[i];
        var g = image[i + 1];
        var b = image[i + 2];
        var alpha = image[i + 3];
        ctx2.fillStyle = "rgba(" + r + "," + g + "," + b + "," + (alpha / 255) + ")";
        ctx2.fillRect(x * zoom, y * zoom, zoom, zoom);
    }
}

코드 동작 방식

  1. 오프스크린 캔버스 생성 및 이미지 그리기 — 화면에 보이지 않는 캔버스를 만들어 원본 이미지를 그립니다.
  2. 픽셀 데이터 추출getImageData() 메서드로 RGBA 픽셀 배열을 가져옵니다. 각 픽셀은 빨강(R), 초록(G), 파랑(B), 알파(A) 순서로 4바이트씩 저장됩니다.
  3. 배율만큼 확대해 다시 그리기 — 각 픽셀을 zoom 크기의 사각형으로 치환해 대상 캔버스(ctx2)에 그립니다. 색상 보간 없이 원래 값을 그대로 사용하므로, 결과물은 최근접 이웃 리샘플링과 동일하게 선명한 경계를 유지합니다.

이 기법은 픽셀 아트 게임 화면 확대, 작은 아이콘 확대처럼 흐릿함 없이 날카로운 픽셀 경계가 필요한 경우에 특히 유용합니다. 간단한 용도라면 CSS image-rendering: pixelated; 한 줄로 충분하고, 더 세밀한 제어가 필요할 때 캔버스 기반 접근을 선택하는 것이 좋습니다.