sharp는 Node.js에서 이미지 크기 변경, 자르기와 형식 변환 등을 수행하는 라이브러리다. 내부에서 libvips를 사용하며 파일·버퍼·스트림을 입력과 출력으로 연결할 수 있다. 브라우저의 CSS로 표시 크기만 바꾸는 것과 달리 실제 이미지 파일의 픽셀과 인코딩 결과를 바꾼다.
작업을 연결하는 파이프라인
입력 뒤에 resize, 색상 변환과 출력 형식 등을 이어 붙이고 toFile이나 toBuffer 같은 출력 메서드로 결과를 만든다. 여러 단계를 하나의 파이프라인으로 표현해 중간 파일을 줄일 수 있다. 메서드를 적은 순서와 지원 조합은 API 계약을 확인해야 하며 모든 변환을 무작정 반복 적용하는 방식은 피한다.
장점은 Node.js 서버나 빌드 도구에서 이미지 처리를 직접 구성하고 자동화하기 쉽다는 것이다. 다양한 출력 형식과 크기 정책을 지원한다. 한계는 네이티브 라이브러리·운영체제·CPU 아키텍처에 맞는 설치가 필요하고, 큰 이미지나 과도한 병렬 처리가 메모리를 많이 쓸 수 있다는 점이다. 모든 동영상 형식을 처리하는 범용 미디어 도구는 아니다.
도서 표지의 작은 WebP 만들기
sharp가 설치된 Node.js 프로젝트와 연습용 cover.jpg를 준비한다. 다음을 thumbnail.mjs로 저장해 실행한다. 원본 비율을 유지하면서 가로 360, 세로 480 안에 들어오게 만들며 작은 원본은 확대하지 않는다. 원본과 출력 이름을 다르게 사용한다.
import sharp from 'sharp';
const result = await sharp('cover.jpg', { limitInputPixels: 40_000_000 })
.rotate()
.resize({ width: 360, height: 480, fit: 'inside', withoutEnlargement: true })
.webp({ quality: 82 })
.toFile('cover-small.webp');
console.log({ width: result.width, height: result.height, bytes: result.size });출력은 최대 경계 안에 들어가며, 원본 비율에 따라 정확히 360×480이 아닐 수 있다. fit: inside는 일부를 잘라 비율을 맞추는 cover와 다르다. 인자 없는 rotate는 방향 메타데이터를 고려해 이미지를 바로 세우는 용도다. quality는 손실 압축 품질 설정이지 목표 바이트 수가 아니다.
이미지 정책과 자원 제한
도서 표지처럼 가장자리의 글자가 중요한 이미지는 무조건 가운데를 잘라 내면 정보가 사라질 수 있다. 반대로 정사각형 카드가 필요하면 잘라낼 영역과 초점 선택을 명시한다. 투명도·애니메이션·색상 프로필·메타데이터 보존은 각각 별도 옵션과 검증 대상이다.
압축 파일이 작아도 디코딩된 픽셀 수가 매우 클 수 있으므로 파일 바이트 제한과 픽셀 제한을 함께 둔다. 업로드 요청마다 무제한 변환을 동시에 시작하지 않고 동시 작업 수를 제어한다. 원본과 출력의 방향·해상도·시각적 품질을 비교하며, 설치된 버전에서 지원하는 포맷과 플랫폼을 확인한 뒤 배포한다.