JavaScript(React)에서 PDF 이미지 교체 및 제거

2026-09-11 09:56:53 Allen Yang
AI Summarize:
ChatGPT
ChatGPT ✓
Claude ✓
Grok ✓
Perplexity ✓
Quick
Quick
Concise overview
Highlights
Key takeaways
Detailed
Structured explanation
Brief
One sentence summary
Summarize |

A PDF document with an image replaced and another deleted using Spire.PDF for JavaScript

지난 분기에 만든 PDF가 아직도 내부에서 유통되고 있지만, 지난달에 로고가 리브랜딩되었고 한 차트에는 더 이상 사실이 아닌 숫자가 표시됩니다. 문서를 처음부터 다시 만들고 싶지는 않을 것입니다. 오래된 이미지를 새 이미지로 교체하거나, 더 이상 사용하지 않는 스탬프나 워터마크를 완전히 제거하기만 하면 됩니다.

Spire.PDF for JavaScript는 PdfImageHelper 클래스를 통해 브라우저에서 두 작업을 모두 처리합니다. 두 작업의 핵심 개념은 동일합니다. 먼저 페이지에서 이미지를 찾은 다음, 해당 이미지에 작업을 수행합니다. GetImagesInfo는 이미지 메타데이터를 읽고, ReplaceImage는 원래 위치를 유지하면서 새 콘텐츠로 교체하며, DeleteImage는 객체를 제거하고 공간을 비워 둡니다. 서버도, 업로드도, Adobe Acrobat도 필요하지 않습니다.

이 문서에서는 다음 방법을 알아봅니다:

  • GetImagesInfo로 페이지의 모든 이미지 찾기
  • 원래 위치와 크기를 유지하면서 이미지 교체하기
  • 이미지를 삭제하고 깨끗한 빈 공간 남기기
  • 인덱스를 모를 때 위치로 올바른 이미지 선택하기
  • 문서의 모든 페이지에서 이미지 정리하기

사전 요구 사항

이 연습에서는 Spire.PDF for JavaScript가 설치되어 있고 WASM 모듈이 초기화된 React 프로젝트가 있다고 가정합니다. 아직 설정하지 않았다면 React 프로젝트에 Spire.PDF for JavaScript 통합하기를 따르세요.

필요한 항목:

  • 이미지가 하나 이상 포함되어 있고 VFS에 로드된 PDF
  • (교체용) 새로 넣을 이미지 파일
  • window.wasmModule.spirepdf를 통해 접근할 수 있는 WASM 모듈

Spire.PDF가 이미지를 찾는 방법

교체와 삭제는 모두 같은 단계에서 시작합니다. 페이지에 어떤 이미지가 있고 어디에 있는지 파악하는 것입니다. PdfImageHelper.GetImagesInfo(page) 메서드는 이미지 정보 객체의 배열을 반환합니다. 각 객체는 다음을 제공합니다:

  • Image — 이미지 데이터 자체(교체할 때 또는 PDF에서 이미지 추출할 때 사용)
  • Bounds — 페이지에서 이미지의 위치와 크기를 설명하는 RectangleF
// Create a PdfImageHelper and inspect the first page
let helper = new pdfModule.PdfImageHelper();
let images = helper.GetImagesInfo(page);

console.log(`Found ${images.length} image(s) on this page`);
for (let i = 0; i < images.length; i++) {
  console.log(`Image ${i}: position=(${images[i].Bounds.X}, ${images[i].Bounds.Y}), size=${images[i].Bounds.Width}x${images[i].Bounds.Height}`);
}

배열 인덱스는 페이지에 이미지가 나타나는 순서를 따르므로 images[0]이 첫 번째, images[1]이 두 번째입니다. 이 배열을 얻고 나면 교체 또는 삭제는 단일 메서드 호출로 수행할 수 있으며, 이는 다음 두 섹션에서 다룹니다.


이미지 교체

교체는 문서 레이아웃을 그대로 유지합니다. 새 이미지는 원래 위치와 자리 표시자 크기를 상속하므로 주변 요소가 이동하지 않습니다. 단계는 다음과 같습니다. PDF와 교체 이미지를 VFS에 로드하고, PDF를 열고, GetImagesInfo를 호출한 다음, 대상 정보 객체와 새 이미지로 ReplaceImage를 호출합니다.

function App() {
  const replaceImageInPdf = 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/`);

    // Load the new image used for replacement into VFS
    const newImageName = 'ChartImage.png';
    await window.spire.FetchFileToVFS(newImageName, "", `${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 page
    let helper = new pdfModule.PdfImageHelper();
    let images = helper.GetImagesInfo(page);

    // Load the new image and replace the first image on the page
    let newImage = pdfModule.PdfImage.FromFile(newImageName);
    helper.ReplaceImage(images[0], newImage);

    // Define the output file name in PDF format
    const outputFileName = 'ReplaceImage.pdf';

    // Save as PDF format
    doc.SaveToFile({ fileName: outputFileName });
    doc.Close();

    // Read the generated PDF file from VFS and trigger download
    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: 'application/pdf' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Replace Image In PDF</h1>
      <button onClick={replaceImageInPdf}>
        Generate
      </button>
    </div>
  );
}

export default App;

이미지를 교체한 후 생성된 PDF 문서

PDF document generated after replacing an image

helper.ReplaceImage(images[0], newImage)는 인덱스 0의 이미지 콘텐츠를 newImage로 바꿉니다. 교체는 원본과 동일한 위치와 동일한 크기로 이루어집니다. 교체 이미지의 가로세로 비율이 다르면 원래 자리 표시자에 맞게 늘어납니다.


이미지 삭제

삭제는 교체와 완전히 동일한 설정을 공유합니다. PDF를 로드하고, 페이지를 가져오고, GetImagesInfo를 호출합니다. 유일한 차이는 마지막 호출입니다. ReplaceImage 대신 대상 정보 객체로 DeleteImage를 호출하면 이미지가 완전히 제거되고 해당 공간은 비어 있게 됩니다.

// Everything above is identical to the replace example:
// load the PDF, get page 0, create the helper, call GetImagesInfo(page)

// Delete the first image on the page
helper.DeleteImage({ imageInfo: images[0] });

이미지를 삭제한 후 생성된 PDF 문서

PDF document generated after deleting an image

helper.DeleteImage({ imageInfo: images[0] })는 인덱스 0의 이미지를 제거합니다. 주변 텍스트, 그래픽, 레이아웃은 변경되지 않으며, 이미지가 차지하던 공간은 리플로우 없이 그냥 비어 있게 됩니다.


위치로 이미지 지정

페이지에 여러 이미지가 있을 때 원하는 이미지가 어느 배열 인덱스인지 모를 수 있습니다. Bounds 속성은 각 이미지의 위치를 알려주고, IntersectsWith를 사용하면 특정 영역 안의 이미지에 작업할 수 있습니다. 머리글 스탬프를 지우거나 항상 같은 위치에 놓이는 차트를 교체할 때 유용합니다.

// Get the image information on the page
let helper = new pdfModule.PdfImageHelper();
let images = helper.GetImagesInfo(page);

// Define the target region (e.g., a stamp area in the bottom-right)
let targetRect = new pdfModule.RectangleF({ x: 400, y: 700, width: 100, height: 80 });

// Iterate through the images and delete those within the target region
for (let i = 0; i < images.length; i++) {
  if (images[i].Bounds.IntersectsWith({ rect: targetRect })) {
    helper.DeleteImage({ imageInfo: images[i] });
    console.log(`Deleted image at position (${images[i].Bounds.X}, ${images[i].Bounds.Y})`);
  }
}

Bounds는 X, Y, Width, Height를 가진 RectangleF이며, 모두 포인트 단위입니다(1포인트 = 1/72인치). 원점 (0, 0)은 페이지의 왼쪽 위 모서리입니다.


모든 페이지 일괄 처리

여러 페이지 문서 전체에서 이미지에 작업하려면 Pages 컬렉션을 반복하면서 페이지마다 동일한 로직을 실행합니다. 아래 예제는 모든 이미지를 삭제합니다. 대신 일괄 교체하려면 DeleteImage를 ReplaceImage로 바꾸세요(반복 전에 새 이미지를 한 번 로드).

const batchDeleteAllImages = 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();

  // Loop through all pages
  for (let pageIndex = 0; pageIndex < doc.Pages.Count; pageIndex++) {
    let page = doc.Pages.get_Item(pageIndex);
    let images = helper.GetImagesInfo(page);

    // Delete all images on this page
    for (let i = 0; i < images.length; i++) {
      helper.DeleteImage({ imageInfo: images[i] });
    }
    console.log(`Page ${pageIndex + 1}: deleted ${images.length} image(s)`);
  }

  const outputFileName = 'AllImagesDeleted.pdf';
  doc.SaveToFile({ fileName: outputFileName });
  doc.Close();

  const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
  const blob = new Blob([fileArray], { type: 'application/pdf' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = outputFileName;
  a.click();
  URL.revokeObjectURL(url);
};

자주 묻는 질문

변경하려는 특정 이미지를 어떻게 찾나요?

GetImagesInfo는 페이지 순서대로 이미지를 반환하므로 images[0], images[1], …은 첫 번째, 두 번째 이미지를 나타냅니다. 순서가 명확하지 않으면 각 객체의 Bounds 속성을 읽어 위치를 확인하고, Bounds.IntersectsWith를 사용해 알려진 영역 안의 이미지를 찾으세요. 위의 위치로 이미지 지정을 참고하세요.

교체하거나 삭제하면 페이지의 나머지 부분이 영향을 받나요?

아니요. 두 작업 모두 이미지 객체 자체만 건드립니다. 교체는 원래 위치와 자리 표시자 크기를 유지하고, 삭제는 빈 공간을 남깁니다. 텍스트, 그래픽, 레이아웃은 영향을 받지 않으며 문서가 리플로우되지 않습니다.

가로세로 비율이 다른 이미지로 교체할 수 있나요?

예 — ReplaceImage는 새 이미지를 원래 자리 표시자에 맞게 늘립니다. 새 이미지의 비율을 유지해야 한다면 이전 이미지를 삭제하고 원하는 정확한 크기로 DrawImage를 사용해 교체 이미지를 추가하세요. JavaScript(React)에서 PDF에 이미지를 추가하는 방법을 참고하세요.

문서에서 모든 이미지를 제거하려면 어떻게 하나요?

doc.Pages.Count를 반복하고, 페이지마다 GetImagesInfo를 호출하고, 각 항목에 DeleteImage를 호출하세요. 모든 페이지 일괄 처리 예제에 전체 코드가 나와 있습니다.


참고 항목