
ExpressJS sharp
Nodejs 환경에서 사용 가능한 이미지 처리 라이브러리이다. 최근 진행했던 프로젝트에서 매우 유용하게 사용했다.
내부는 libvips라는 C언어 기반으로 구현되었으며 다양한 형식을 지원하고 퍼포먼스 또한 훌륭하여 노드 진영에서 이미지 관련 라이브러리 중 비교할 대상이 없다.

설치
sharp는 다양한 운영체제를 지원한다. 플랫폼을 별도로 명시하지 않으면 현재 자신이 사용하고 있는 운영체제를 기준으로 설치된다. 운영체제별로 기능의 차이는 없으며 윈도우 플랫폼이 설치된 node_modules 폴더를 리눅스에 옮겨 실행하면 문제가 되므로 반드시 개인에 맞는 실행 환경을 확인해야 한다.
npm i sharp // 자신의 운영체제
npm i --platform=win32 // 윈도우
npm i --platform=linux // 리눅스
사용
모듈 임포트 후 이미지를 인수로 넣어 메서드 체이닝하는 방식으로 사용한다. 생각보다 메서드 수가 많으니 공식 문서를 참고해 개인의 서비스에 맞게 적용하면 된다.
1. 메타데이터(metadata)
이미지에 대한 메타데이터 확인 종류는 매우 많으니 자세한 옵션은 공식 문서 참고
import sharp from "sharp";
const {
format,
width,
height,
hasAlpha
} = await sharp("./88_KB.png").metadata();
console.log(width, height, hasAlpha);
2. 리사이징(resize)
이미지 크기를 설정한 가로/세로로 리사이징한다. fit은 리사이징 시 가로/세로 비율 처리 로직
- cover: 가로/세로 비율을 유지하고 이미지에 맞게 조절
- contain: 가로/세로 비율을 유지하고 필요시 레터박스 추가
- fill: 가로/세로 비율을 유지하지 않고 지정된 수치로 조절
- inside: 가로/세로 비율을 유지하고 지정된 수치를 작거나 같게 유지하면서 가능한 크게 조절
- outside: 가로/세로 비율을 유지하고 지정된 수치를 크거나 같게 유지하면서 가능한 작게 조절
import sharp from "sharp";
const format = "png";
// 924 883
const result = await sharp("./88kb.png")
.toFormat(format)
.resize(400, 400, { fit: "inside" })
.toFile("resize-88kb.png", (err, result) => {
console.log(result);
})
.toBuffer();
전 | 후 | |
사이즈(width, height) | 924, 883 | 400, 382 |
용량(mb) | 88 | 43 |
문제
최근 프로젝트를 진행하면서 특정 PNG 이미지를 리사이징 할 경우 리사이징 전 용량보다 리사이징 후 용량이 더 커져버리는 현상을 식별했다. 정상적인 이미지와 특정 PNG 이미지의 메타데이터를 비교하였는데 파일 이름만 다를 뿐 다른 데이터들은 모두 동일했다.
import sharp from "sharp";
const format = "png";
const result = await sharp("./90kb.png")
.resize(600, 600, { fit: "inside" })
.toFile("90resize.png")
const problem = await sharp("./90kb.png").withMetadata();
const noProblem = await sharp("./66kb.png").withMetadata();
console.log(before);
console.log(after);
전 | 후 | |
사이즈(width, height) | 1024, 1024 | 600, 600 |
용량(mb) | 91 | 128 |
해결
리사이징 전보다 리사이징 후 이미지의 용량이 커져버린다면 실제 서비스 환경에서 매우 치명적이다. 공식 문서를 한참 동안 읽어보았지만 해결 방법을 찾을 수 없어 공식 github 이슈에 질문을 하여 해결하였다. png 메서드의 옵션으로 palette 설정이 있는데 true로 설정(default = false) 해주면 알파 투명 지원 기능으로 팔레트 기반 이미지로 양자화 시킨다고 한다. 이미지의 샘플링과 양자화란 기법이 있는데 이 부분은 개발자의 영역이 아닌 거 같아 추후 공부할 예정이다.

import sharp from "sharp";
const format = "png";
const result = await sharp("./90kb.png")
.resize(600, 600, { fit: "inside" })
.png({ palette: true})
.toFile("90resize.png")
전 | 후 | |
사이즈(width, height) | 1024, 1024 | 600, 600 |
용량(mb) | 91 | 47 |
참고 자료
https://sharp.pixelplumbing.com/install
https://github.com/lovell/sharp
https://github.com/lovell/sharp/issues/3398
'서버 > Express' 카테고리의 다른 글
ExpressJS Google Spreadsheet API (0) | 2023.01.06 |
---|---|
ExpressJS typedi (0) | 2022.11.01 |
ExpressJS Jest ES6 import export (0) | 2022.08.10 |
ExpressJS express-validator 유효성 검사 (0) | 2022.06.23 |
ExpressJS nodemailer 비밀번호 초기화 (0) | 2022.06.21 |