
40페이지 분량의 보고서를 받았고 슬라이드 덱에 넣을 8개의 차트가 필요하거나, 공급업체 카탈로그에서 제품 사진을 추출하고 싶을 수 있습니다. 문제는 PDF가 브라우저의 기본 제공 API로는 읽을 수 없는 내부 스트림 형식으로 이미지를 저장한다는 점입니다. 따라서 "마우스 오른쪽 버튼 클릭 후 이미지 저장" 경로가 없습니다.
Spire.PDF for JavaScript는 PdfImageHelper 클래스를 통해 이러한 스트림을 읽어줍니다. GetImagesInfo는 페이지의 모든 이미지 객체를 검색하고, 각 객체의 Image.Save 메서드는 이를 독립 실행형 파일로 기록합니다. 모든 것이 WebAssembly를 통해 브라우저에서 실행되므로 PDF가 기기를 떠나지 않으며 서버나 외부 도구가 필요하지 않습니다.
이 문서에서는 다음 방법을 알아봅니다:
-
GetImagesInfo로 PDF 페이지에서 이미지 객체 검색 - 각 이미지를 VFS에 저장하고 다운로드 트리거
- 여러 페이지 문서의 모든 페이지 순회
- 추출된 파일에 일관된 이름 지정 체계 적용
- 추출된 이미지를 React UI 내에서 직접 사용
사전 요구 사항
이 연습에서는 Spire.PDF for JavaScript가 설치되고 WASM 모듈이 초기화된 React 프로젝트가 있다고 가정합니다. 설정 지침은 React 프로젝트에서 Spire.PDF for JavaScript 통합을 참조하세요.
다음이 필요합니다:
- 이미지가 포함되어 있고 VFS에 로드된 PDF
-
window.wasmModule.spirepdf를 통해 접근할 수 있는 WASM 모듈
단일 페이지에서 이미지 추출
기본 추출 워크플로는 한 페이지에서 모든 이미지를 검색하고, 각 이미지를 VFS에 저장한 다음 다운로드를 트리거합니다:
-
PDF를 VFS에 로드하고
PdfDocument로 엽니다 - 문서에서 대상 페이지를 가져옵니다
-
GetImagesInfo를 호출하여 이미지 정보 객체 배열을 검색합니다 -
배열을 반복하면서
images[i].Image.Save()를 호출하여 각 이미지를 VFS에 기록합니다 - VFS에서 읽고 추출된 각 이미지에 대해 브라우저 다운로드를 트리거합니다
function App() {
const extractImagesFromPdf = async () => {
// Get the Spire.PDF WASM module
const pdfModule = window.wasmModule?.spirepdf;
// Check if the WASM module is ready
if (!pdfModule) {
alert('Spire.PDF is not ready yet');
return;
}
// Load the PDF file into VFS
const inputFileName = 'Business_Data_Overview.pdf';
await window.spire.FetchFileToVFS(inputFileName, "", `${process.env.PUBLIC_URL}/data/`);
// Create a PdfDocument object and load the PDF document
let doc = new pdfModule.PdfDocument();
doc.LoadFromFile(inputFileName);
// Get the first page
let page = doc.Pages.get_Item(0);
// Create a PdfImageHelper object and get the image information on the first page
let helper = new pdfModule.PdfImageHelper();
let images = helper.GetImagesInfo(page);
// Iterate through the images on the page, save each as a separate image file, and trigger download
for (let i = 0; i < images.length; i++) {
const outputFileName = `ExtractedImage_${i + 1}.png`;
images[i].Image.Save({ fileName: outputFileName });
// Read the extracted image file from VFS and trigger download
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'image/png' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
}
doc.Close();
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Extract Images From PDF</h1>
<button onClick={extractImagesFromPdf}>
Generate
</button>
</div>
);
}
export default App;
PDF에서 추출된 이미지 파일

코드가 하는 일:
-
helper.GetImagesInfo(page)는 지정된 페이지에 대한 이미지 정보 객체 배열을 반환합니다. 각 객체에는 이미지 데이터에 접근할 수 있는Image속성이 있습니다. -
images[i].Image.Save({ fileName: outputFileName })는 이미지를 PNG 파일로 VFS에 기록합니다. - VFS 읽기 + Blob + 다운로드 패턴은 PDF 출력에 사용되는 것과 동일하지만
type: 'application/pdf'대신type: 'image/png'를 사용합니다. - 추출은 읽기 전용 작업입니다 — 원본 PDF 문서는 수정되지 않습니다. 이미지를 단순히 읽어오는 대신 그 자리에서 변경하거나 제거하려면 JavaScript(React)에서 PDF의 이미지 교체 및 제거를 참조하세요.
모든 페이지에서 이미지 추출
위 예제는 첫 번째 페이지에서만 추출합니다. 제품 카탈로그나 연간 보고서와 같은 여러 페이지 문서의 경우 일반적으로 모든 페이지의 모든 이미지를 원합니다. 문서의 페이지를 순회하는 외부 루프를 추가하기만 하면 됩니다:
const extractAllImages = async () => {
const pdfModule = window.wasmModule?.spirepdf;
if (!pdfModule) return;
await window.spire.FetchFileToVFS('Business_Data_Overview.pdf', "", `${process.env.PUBLIC_URL}/data/`);
let doc = new pdfModule.PdfDocument();
doc.LoadFromFile('Business_Data_Overview.pdf');
let helper = new pdfModule.PdfImageHelper();
let imageCount = 0;
// Loop through all pages in the document
for (let pageIndex = 0; pageIndex < doc.Pages.Count; pageIndex++) {
let page = doc.Pages.get_Item(pageIndex);
let images = helper.GetImagesInfo(page);
// Extract each image on this page
for (let i = 0; i < images.length; i++) {
imageCount++;
const outputFileName = `Page${pageIndex + 1}_Image${i + 1}.png`;
images[i].Image.Save({ fileName: outputFileName });
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'image/png' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
}
}
console.log(`Total images extracted: ${imageCount}`);
doc.Close();
};
단일 페이지 예제와의 주요 차이점: 외부 for 루프가 doc.Pages.Count를 반복하며, 파일 이름에 페이지 번호와 이미지 인덱스가 모두 포함됩니다(Page1_Image1.png, Page1_Image2.png, Page2_Image1.png 등). 이렇게 하면 추출된 파일을 체계적으로 관리할 수 있습니다.
추출된 파일 이름 지정
일관된 이름 지정 전략은 어떤 이미지가 어느 페이지와 위치에서 왔는지 추적하는 데 도움이 됩니다. 일반적인 패턴은 다음과 같습니다:
순차 번호 매기기 — 가장 간단하며 단일 페이지 추출에 적합합니다:
const outputFileName = `ExtractedImage_${i + 1}.png`;
// ExtractedImage_1.png, ExtractedImage_2.png, ...
페이지 및 인덱스 — 다중 페이지 추출에 가장 적합하며 원본 위치를 유지합니다:
const outputFileName = `Page${pageIndex + 1}_Image${i + 1}.png`;
// Page1_Image1.png, Page1_Image2.png, Page2_Image1.png, ...
타임스탬프 — 한 세션에서 여러 문서를 추출할 때 유용합니다:
const timestamp = Date.now();
const outputFileName = `Extracted_${timestamp}_Page${pageIndex + 1}_${i + 1}.png`;
원본 문서 이름 기반 — 출처 추적에 도움이 됩니다:
const sourceName = 'Business_Data_Overview';
const outputFileName = `${sourceName}_p${pageIndex + 1}_img${i + 1}.png`;
// Business_Data_Overview_p1_img1.png, ...
추출된 이미지 작업
다운로드를 트리거하는 대신(또는 추가로) 추출된 이미지 데이터를 React 애플리케이션에서 직접 사용할 수 있습니다. 예를 들어 추출된 이미지를 갤러리에 표시할 수 있습니다:
const extractAndDisplay = async () => {
const pdfModule = window.wasmModule?.spirepdf;
if (!pdfModule) return;
await window.spire.FetchFileToVFS('Business_Data_Overview.pdf', "", `${process.env.PUBLIC_URL}/data/`);
let doc = new pdfModule.PdfDocument();
doc.LoadFromFile('Business_Data_Overview.pdf');
let helper = new pdfModule.PdfImageHelper();
let extractedImageUrls = [];
for (let pageIndex = 0; pageIndex < doc.Pages.Count; pageIndex++) {
let page = doc.Pages.get_Item(pageIndex);
let images = helper.GetImagesInfo(page);
for (let i = 0; i < images.length; i++) {
const tempName = `temp_p${pageIndex + 1}_${i + 1}.png`;
images[i].Image.Save({ fileName: tempName });
const fileArray = window.dotnetRuntime.Module.FS.readFile(tempName);
const blob = new Blob([fileArray], { type: 'image/png' });
const url = URL.createObjectURL(blob);
extractedImageUrls.push(url);
}
}
doc.Close();
// Now you have an array of object URLs you can use in <img> tags
// setExtractedImages(extractedImageUrls); // if using state
console.log(`Extracted ${extractedImageUrls.length} images ready for display`);
};
이 접근 방식을 사용하면 <img src={url} /> 요소에 직접 사용할 수 있는 객체 URL을 얻을 수 있으므로 미리보기 갤러리를 만들거나, 사용자가 특정 이미지를 선택하게 하거나, 이미지를 애플리케이션의 다른 부분에 전달하기 쉽습니다. 이미지 데이터를 확보한 후에는 PDF에 이미지를 추가하는 그리기 로직이 자연스러운 다음 단계입니다.
참고: 사용을 마친 각 객체 URL에 대해
URL.revokeObjectURL(url)를 호출하여 메모리를 해제해야 합니다. 갤러리에서 이미지를 표시하는 경우 갤러리 컴포넌트가 언마운트될 때 URL을 해제하세요.
FAQ
이미지를 추출하면 원본 PDF가 수정되나요?
아니요. 이미지 추출은 읽기 전용 작업입니다. GetImagesInfo는 문서를 수정하지 않고 PDF에서 이미지 데이터를 읽으며, Image.Save는 VFS에 복사본을 기록합니다. 원본 PDF는 변경되지 않습니다.
추출된 이미지는 어떤 형식으로 저장되나요?
이 문서의 예제는 추출된 이미지를 PNG 파일(.png)로 저장합니다. Image.Save에 전달하는 파일 확장자가 출력 형식을 결정하므로 사용 사례에 따라 다른 형식을 선택할 수 있습니다.
특정 페이지 범위에서 이미지를 추출하려면 어떻게 하나요?
doc.Pages.Count로 모든 페이지를 반복하는 대신 원하는 범위를 반복하세요. 예를 들어 3페이지부터 5페이지까지(0부터 시작하는 인덱스로 2~4) 추출하려면:
for (let pageIndex = 2; pageIndex <= 4 && pageIndex < doc.Pages.Count; pageIndex++) {
let page = doc.Pages.get_Item(pageIndex);
let images = helper.GetImagesInfo(page);
// ... save and download each image
}
다운로드하지 않고 이미지를 추출하여 React 앱에 표시할 수 있나요?
예. 다운로드 링크를 만드는 대신 URL.createObjectURL(blob)으로 객체 URL을 만들고 이를 <img> 요소의 src로 사용하세요. 위의 추출된 이미지 작업 섹션에서 코드 예제를 참조하세요.
페이지에 이미지가 없으면 어떻게 되나요?
GetImagesInfo는 이미지가 없는 페이지에 대해 빈 배열을 반환합니다. for 루프가 실행되지 않으므로 파일이 생성되지 않고 오류도 발생하지 않습니다. 모든 페이지에서 안전하게 실행할 수 있습니다.