웹 애플리케이션에서 PDF 파일의 썸네일을 생성하는 기능은 사용자 경험을 향상하는 데 중요한 요소입니다. 특히, PDF 파일을 업로드할 때 미리보기를 제공하면 사용자가 보다 직관적으로 파일을 확인할 수 있습니다. 이번 글에서는 PDF 파일을 이미지로 변환하여 추출하는 방법을 소개합니다.
📌 PDF를 이미지로 변환하는 과정
1. pdfjs-dist 설정
PDF 파일을 다루기 위해 pdfjs-dist 라이브러리를 사용합니다. 먼저, GlobalWorkerOptions.workerSrc를 설정해야 합니다.
import * as pdfjsLib from 'pdfjs-dist'
pdfjsLib.GlobalWorkerOptions.workerSrc = '/pdfjs/pdf.worker.min.js'
이 설정을 통해 PDF.js가 PDF를 분석하는 작업을 백그라운드에서 수행할 수 있게합니다.
2. PDF를 이미지로 변환하는 함수 구현
아래는 PDF 파일을 받아서 첫 번째 페이지를 WebP 이미지 파일로 변환하는 함수입니다.
interface ExtractImageFromPdf {
file: File;
pageNumber?: number;
width?: number;
height?: number;
extension?: 'webp' | 'png' | 'jpeg' | 'jpg';
}
export const extractImageFromPdf = async ({
file,
pageNumber = 1,
width = 600,
height = 400,
extension = 'webp',
}: ExtractImageFromPdf): Promise<File> => {
const fileURL = URL.createObjectURL(file);
const pdf = await pdfjsLib.getDocument({ url: fileURL }).promise;
URL.revokeObjectURL(fileURL); // 메모리 누수 방지를 위해 URL 해제
// 페이지 가져오기
const page = await pdf.getPage(pageNumber);
const viewport = page.getViewport({ scale: 1 });
const { width: originalWidth, height: originalHeight } = viewport;
// 가로/세로 비율에 따른 최대 크기 설정
const isLandscape = originalWidth > originalHeight;
const maxWidth = isLandscape ? width : height;
const maxHeight = isLandscape ? height : width;
const scale = Math.min(maxWidth / originalWidth, maxHeight / originalHeight);
const canvasWidth = originalWidth * scale;
const canvasHeight = originalHeight * scale;
// 캔버스 생성 및 설정
const canvas = document.createElement('canvas');
canvas.width = canvasWidth;
canvas.height = canvasHeight;
const context = canvas.getContext('2d');
if (!context) throw new Error('Failed to get canvas context');
// PDF 페이지를 캔버스에 렌더링
const adjustedViewport = page.getViewport({ scale });
await page.render({ canvasContext: context, viewport: adjustedViewport })
.promise;
// 캔버스를 이미지 Blob으로 변환
const blob = await new Promise<Blob>((resolve) => {
canvas.toBlob((blob) => {
if (!blob) throw new Error('Failed to convert canvas to blob');
resolve(blob);
}, `image/${extension}`);
});
// Blob을 File 객체로 변환
const fileOriginalName = file.name.split('.').slice(0, -1).join('.');
return new File([blob], `${fileOriginalName}.${extension}}`, {
type: `image/${extension}`,
});
};
✅ 코드 설명
- PDF 파일을 객체 URL로 변환
- URL.createObjectURL(file)을 사용해 PDF를 로드할 수 있도록 만듭니다.
- 이후 pdfjsLib.getDocument({ url: fileURL })를 이용해 PDF 문서를 가져옵니다.
- URL.revokeObjectURL(fileURL)을 호출해 메모리 누수를 방지합니다.
- PDF의 첫 번째 페이지를 캔버스에 렌더링
- pdf.getPage(1)을 호출해 첫 번째 페이지를 가져옵니다.
- 페이지의 원래 크기를 구한 후, 최대 크기(558px × 400px)에 맞춰 비율을 유지한 채 축소합니다.
- canvas.getContext('2d')를 이용해 2D 컨텍스트를 가져온 후 page.render()를 사용해 렌더링합니다.
- 렌더링된 이미지를 Blob 및 File 객체로 변환
- canvas.toBlob()을 사용해 WebP 이미지로 변환합니다.
- 이를 File 객체로 변환해 파일 업로드 등에 활용할 수 있도록 합니다.
마무리
위 코드를 활용하면 PDF 파일을 업로드할 때 자동으로 썸네일 이미지를 생성할 수 있습니다.
특히, WebP 포맷을 사용하면 파일 크기를 줄이면서도 고품질 이미지를 유지할 수 있습니다.
이제 이 기능을 React, Next.js 등과 함께 활용해 PDF 파일 업로드 시 미리보기를 제공하는 UI를 구현해 보세요!