Search

Search through articles and snippets by title, tags, or content.

Back to Articles
Next.js에서 이미지 EXIF 메타데이터 완벽하게 다루기: 라이브러리 비교와 실무 패턴
TypeScriptNextjsEXIFImageMetadata

Next.js에서 이미지 EXIF 메타데이터 완벽하게 다루기: 라이브러리 비교와 실무 패턴

Next.js 프로젝트에서 이미지의 GPS, 촬영 정보, 회전 값을 읽기 위해 어떤 라이브러리를 써야 할까요? exifr, exif-js, sharp의 특징과 실무 추천 조합을 정리했습니다.

D
DevBlog
Feb 14, 2026
7 min read

웹 서비스를 개발하다 보면 사용자가 업로드한 이미지에서 촬영 장소(GPS), 촬영 기기, 혹은 사진의 회전 방향(Orientation) 정보를 추출해야 할 때가 있습니다. 특히 Next.js 환경에서는 클라이언트(브라우저)와 서버(API Route/Server Components) 양쪽에서 이미지를 다뤄야 하므로 상황에 맞는 라이브러리 선택이 매우 중요합니다.

오늘은 Next.js 프로젝트에서 이미지 EXIF 메타데이터를 처리하는 가장 효율적인 방법을 비교 분석해 보겠습니다.


📊 EXIF 라이브러리 3종 비교

현재 생태계에서 주로 사용되는 라이브러리들의 장단점을 한눈에 비교해 보세요.

라이브러리환경주요 특징추천 상황
exif-js브라우저 전용가장 오래된 라이브러리, 업데이트 저조레거시 프로젝트 유지보수
exif-readerNode.js 중심sharp와 연동성 우수, 버퍼 파싱 전용서버사이드 전용 처리
exifrIsomorphic가장 빠름, 거의 모든 포맷 지원, 브라우저/서버 공용대부분의 신규 프로젝트

1. 클라이언트와 서버를 아우르는 'exifr'

현재 가장 추천하는 라이브러리는 exifr입니다. 브라우저의 File, Blob뿐만 아니라 Node.js의 Buffer도 완벽하게 지원하며 속도가 압도적으로 빠릅니다.

주요 장점

  • 다양한 포맷 지원: JPEG는 물론 HEIC, AVIF, PNG, TIFF까지 지원합니다.
  • 부분 파싱: 파일 전체를 읽지 않고 메타데이터 세그먼트만 골라 읽어 성능을 극대화합니다.
  • 유용한 유틸리티: GPS 좌표 변환(exifr.gps())이나 회전 값 계산(exifr.rotation()) 기능을 내장하고 있습니다.

사용 예시 (Next.js 클라이언트 컴포넌트)

import exifr from "exifr";
 
const handleUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
  const file = e.target.files?.[0];
  if (!file) return;
 
  // 모든 EXIF 데이터 파싱
  const data = await exifr.parse(file);
  console.log(`기기: ${data.Make} ${data.Model}`);
 
  // GPS 정보만 따로 추출 (도 단위 변환 완료)
  const gps = await exifr.gps(file);
  console.log(`위도: ${gps?.latitude}, 경도: ${gps?.longitude}`);
};

2. 서버사이드 최강 조합: 'sharp' + 'exifr'

Next.js API Route나 Server Actions에서 이미지를 리사이징하면서 메타데이터를 추출해야 한다면, 이미지 처리 라이브러리의 표준인 sharp와 exifr를 함께 사용하는 것이 실무 정석 패턴입니다.

왜 이 조합인가요?

  1. sharp: 이미지 최적화(WebP 변환 등)와 EXIF 기반 자동 회전(rotate())에 탁월합니다.
  2. exifr: sharp가 제공하는 원시 EXIF 버퍼를 가장 정밀하게 객체화해줍니다.

실무 추천 코드 (Next.js API Route)

import sharp from "sharp";
import exifr from "exifr";
 
export async function POST(req: Request) {
  const formData = await req.formData();
  const file = formData.get("image") as File;
  const buffer = Buffer.from(await file.arrayBuffer());
 
  // 1. sharp로 이미지 기본 정보 및 EXIF 버퍼 추출
  const image = sharp(buffer);
  const metadata = await image.metadata();
 
  // 2. exifr로 상세 EXIF 정보 파싱
  const detailedExif = await exifr.parse(buffer);
 
  // 3. 이미지 최적화 (EXIF 유지하며 리사이징)
  const optimizedImage = await image
    .resize(1200)
    .withMetadata() // 이 함수를 호출해야 EXIF가 유지됩니다!
    .toBuffer();
 
  return Response.json({ exif: detailedExif });
}

3. 추출 가능한 데이터 종류

exifr을 사용하면 다음과 같은 정보들을 손쉽게 가져올 수 있습니다.

① 카메라 및 촬영 정보 (TIFF/EXIF)

  • Make, Model: 제조사 및 기기명
  • DateTimeOriginal: 실제 사진이 찍힌 시간
  • ExposureTime, FNumber, ISO: 노출 값

② 위치 정보 (GPS)

  • latitude, longitude: 위경도 좌표
  • GPSAltitude: 고도 정보

③ 이미지 방향 (Orientation)

  • 사진이 가로로 찍혔는지, 세로로 찍혔는지 혹은 뒤집혔는지 나타내는 1~8 사이의 값입니다.

⚠️ 실무 주의사항

  1. 개인정보 보호: EXIF에는 상세한 위치 정보가 포함될 수 있습니다. 커뮤니티나 SNS 서비스를 만든다면, 서버에서 처리 후 사용자에게 보여줄 때는 메타데이터를 제거(sharp에서 withMetadata() 제외)하는 보안 절차가 필요합니다.
  2. 포맷별 제한: PNG나 WebP는 JPEG에 비해 메타데이터 지원이 제한적입니다. 라이브러리가 해당 포맷의 어떤 세그먼트(XMP 등)를 지원하는지 확인하세요.
  3. 번들 사이즈: exifr은 기능이 많은 만큼 용량이 있을 수 있습니다. 브라우저에서 사용할 때는 exifr/dist/lite.umd.js 같은 라이트 버전을 고려해 보세요.

결론

Next.js 프로젝트에서 이미지 메타데이터를 다룬다면 고민하지 말고 **exifr**을 선택하세요. 서버사이드 이미지 가공이 동반된다면 **sharp**와의 조합이 최고의 퍼포먼스를 보여줍니다.

혹시 특정 기기(iPhone HEIC 등)에서 발생하는 메타데이터 이슈를 겪고 계신가요? 상황을 알려주시면 더 자세한 해결 방법을 찾아드릴 수 있습니다!

Comments