JavaScript(React)에서 PDF를 그레이스케일로 변환하는 방법

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

Converting a color PDF to a grayscale document in the browser with Spire.PDF for JavaScript

색상이 많은 보고서를 사무실 흑백 레이저 프린터로 보내면 두 번 비용을 치르게 됩니다. 한 번은 프린터가 CMYK 점으로 회색을 흉내 내느라 낭비하는 토너이고, 또 한 번은 결과 품질입니다. 스크린과 차트 채우기가 깔끔한 톤 대신 탁한 반점으로 변합니다. 같은 파일을 기록 보관소에 보내면 색상은 쓸모없는 것보다 더 나쁩니다. 별색은 변하고, 색상 관리는 기기마다 달라지며, 다시 인쇄할 때마다 이전과 조금씩 다르게 나옵니다. 그레이스케일은 이 두 작업 모두가 실제로 원하는 형식이며, PDF를 코드로 다루기 시작하면 단 한 번의 호출로 멀리 떨어져 있지 않습니다.

이 문서에서는 Spire.PDF for JavaScript를 사용하여 브라우저 내에서 PDF를 그레이스케일 문서로 변환합니다. 이 라이브러리는 WebAssembly로 컴파일되고 가상 파일 시스템(VFS)을 통해 문서를 처리하므로, 파일은 사용자 컴퓨터에서 읽고 다시 작성되며 변환 서비스에 아무것도 전달되지 않습니다.

프로젝트 설정은 React 프로젝트에서 Spire.PDF for JavaScript 통합하기를 따르세요. 아래 예제는 패키지가 설치되어 있고 WebAssembly 모듈의 초기화가 완료되었다고 가정합니다.


PDF를 그레이스케일로 변환하는 이유(그리고 그것이 잘못된 선택인 경우)

세 가지 상황이 반복적으로 발생합니다:

  • 단색 하드웨어에서 인쇄. 흑백 레이저 프린터에는 토너가 하나뿐입니다. 컬러 PDF를 넘기면 모든 색을 하프톤 패턴으로 근사해야 하므로, 색상 텍스트와 얇은 차트 선이 흐릿하게 나옵니다. 그레이스케일 소스는 추측을 없애줍니다. 프린터는 해석할 색상이 아니라 톤을 받습니다.
  • 기록 및 보관. 장기 저장 표준은 고정된, 장치 독립적인 모양을 기준으로 작성됩니다. 그레이스케일 문서는 모든 프린터와 스캐너에서 동일하게 재현되므로 보관된 사본이 달라질 수 없습니다.
  • 스캔 및 인덱싱 파이프라인. 문서를 스캔하고 OCR한 후에는 색상이 인덱스가 사용할 수 있는 정보를 전혀 담지 않습니다. 색상은 그저 무게일 뿐입니다.

그대로 두어야 하는 경우도 있습니다. 색상이 의미론적 역할을 하는 경우, 예를 들어 각 시리즈가 다른 색조인 차트, 브랜드 자산, 사진 포트폴리오 같은 경우 그레이스케일 변환은 독자가 필요로 하는 바로 그 요소를 파괴합니다. 실제 문제가 크기일 때도 잘못된 도구입니다. 더 저렴한 인쇄가 아니라 더 작은 파일이 목표라면 그레이스케일은 이미지만 공격하고 글꼴과 콘텐츠 스트림은 무시합니다. 그런 작업은 대신 압축기가 할 일입니다.


그레이스케일이 실제로 바꾸는 것

"그레이스케일"이 페이지를 그림으로 다시 렌더링한다는 의미라고 쉽게 가정할 수 있습니다. 그렇지 않습니다. 변환은 객체 수준에서 작동합니다:

페이지 부분 발생하는 일
컬러 이미지 단일 채널 그레이스케일로 다시 인코딩되며, 세 가지 색상 채널 대신 픽셀당 하나의 휘도 값을 가짐
텍스트 텍스트로 그대로 유지됨 — 여전히 선택, 검색, 복사 가능
레이아웃 및 페이지 수 변경되지 않음. 아무것도 잘리거나 이동되거나 제거되지 않음
문서 메타데이터 유지됨

이미지가 스크린샷으로 래스터화되는 대신 다시 인코딩되므로, 출력은 더 작은 색 공간을 가진 일반 PDF이지 PDF의 그림이 아닙니다. 이 차이는 누군가 결과를 검색하거나 텍스트 한 줄을 선택하려는 순간 중요해집니다.


문서를 그레이스케일로 변환하기

두 멤버가 작업을 수행합니다. 입력 파일을 PdfGrayConverter 생성자에 전달한 다음 출력 파일과 함께 ToGrayPdf를 호출합니다. 나머지 컴포넌트는 일반적인 VFS 로드와 Blob 다운로드입니다.

function App() {
  const convertToGrayscale = async () => {
    // Get the Spire.PDF WASM module
    const pdfModule = window.wasmModule?.spirepdf;

    // Check whether the module is ready
    if (!pdfModule) {
      alert('Spire.PDF is not ready yet');
      return;
    }

    // Load the PDF file to be converted into the VFS
    const inputFileName = 'Business_Data_Overview.pdf';
    await window.spire.FetchFileToVFS(inputFileName, "", `${process.env.PUBLIC_URL}/data/`);

    // Define the output file name
    const outputFileName = 'GrayscaleDocument.pdf';

    // Construct the grayscale converter from the input file and write out the grayscale document
    const converter = new pdfModule.PdfGrayConverter({ filePath: inputFileName });
    converter.ToGrayPdf({ filePath: outputFileName });
    converter.Dispose();

    // Read the generated file from the VFS and trigger the 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>Convert PDF to Grayscale</h1>
      <button onClick={convertToGrayscale}>
        Start Converting
      </button>
    </div>
  );
}

export default App;

세 가지 세부 사항을 눈여겨볼 가치가 있습니다. ToGrayPdf는 새 파일을 작성합니다. VFS의 입력은 그대로 남으므로 "컬러 버전 유지" 옵션은 비용이 들지 않습니다. Dispose는 파일이 작성되면 변환기를 해제합니다. 그리고 페이지의 컬러 이미지가 이 호출이 실제로 다시 작성하는 대상이며, 텍스트는 결코 이미지가 되지 않습니다.

그레이스케일 변환 후의 샘플 문서. 컬러 차트가 그레이스케일로 바뀌었습니다

The sample document after grayscaling, with the color charts turned to grayscale


그레이스케일 vs 채도 감소 vs 흑백

일상적인 사용에서 세 가지 서로 다른 결과가 모두 "그레이스케일"이라고 불리지만, 같은 파일이 아닙니다:

출력 저장 방식 이미지 데이터 크기 적합한 용도
진정한 그레이스케일 단일 채널, DeviceGray 가장 작음 — 픽셀당 하나의 값 인쇄, 보관, 일반 문서
채도 감소 색상 세 개의 동일한 채널, R=G=B인 DeviceRGB 대략 그레이스케일 데이터의 세 배 파일이 이미 존재할 때 빠른 시각적 필터
임계값 흑백 픽셀당 1비트, 톤 없음 매우 작음 입자가 세부 정보가 아니라 노이즈인 스캔한 텍스트 페이지

화면에서는 처음 두 가지를 구분할 수 없습니다. 차이는 전적으로 각 픽셀이 차지하는 바이트 수와 프린터가 이를 해석해야 하는 방식에 있습니다. 임계값 변환은 완전히 다른 작업입니다. 중간 톤을 없애므로 사진은 얼룩으로 변하고 선 그림과 깨끗한 텍스트만 살아남습니다.

변환기는 첫 번째 종류, 즉 단일 채널 그레이스케일 이미지를 작성합니다. 그래서 세 가지 중 저장 비용이 가장 저렴합니다.


파일 크기 부작용

그레이스케일은 압축 기능은 아니지만 파일을 줄여 주며, 그 이유를 아는 것이 좋습니다. 샘플 문서에서 컬러 이미지는 총 약 66KB의 3채널 PNG였고, 변환 후 같은 이미지는 약 31KB가 되었습니다. 전체 파일은 82KB에서 44KB로 줄었습니다. 대략 46% 감소였으며, 순전히 색상 채널을 제거하여 달성한 것입니다. 페이지 수와 텍스트는 전혀 변하지 않았습니다.

이는 잉크 절약과 함께 무료로 얻어집니다. 하지만 숫자를 올바르게 읽어야 합니다. 이득은 파일에서 비트맵이 차지하는 비율에 따라 달라집니다. 대부분 텍스트와 벡터 아트로 이루어진 문서는 다시 인코딩할 비트맵이 거의 없으므로 그레이스케일로 만들어도 크기가 거의 변하지 않습니다. 그리고 크기가 실제 목표라면 이미지는 무게가 숨는 세 곳 중 하나일 뿐입니다. JavaScript(React)에서 PDF 파일 크기 줄이기에서 나머지 두 가지를 다룹니다.


React UI에 연결하기

실제 컴포넌트에서는 위 패턴에 두 가지 조정이 필요합니다.

alert를 그대로 두지 마세요. WebAssembly 모듈은 비동기적으로 로드되므로, 변환기가 존재하기 전에 첫 클릭이 들어올 수 있습니다. 대화상자로 사용자를 방해하는 대신 모듈이 준비되었다고 보고할 때까지 버튼을 비활성화하세요:

// The module may not have finished loading on the first render
const [ready, setReady] = useState(false);
// ...
<button disabled={!ready} onClick={convertToGrayscale}>Convert to Grayscale</button>

같은 호출을 일괄 처리하세요. 변환기는 한 번에 하나의 파일을 받아 하나의 파일을 작성하므로, 문서 폴더는 그냥 반복문입니다. 동일한 생성자, 동일한 메서드, 입력마다 다른 출력 이름을 사용합니다:

// The converter is a one-file operation, so a batch is a loop
for (const name of inputNames) {
  await window.spire.FetchFileToVFS(name, "", `${process.env.PUBLIC_URL}/data/`);
  const out = name.replace(/\.pdf$/i, '-gray.pdf');
  const converter = new pdfModule.PdfGrayConverter({ filePath: name });
  converter.ToGrayPdf({ filePath: out });
  converter.Dispose();
  // read out from the VFS and download (or report per-file sizes)
}

원본과 그레이스케일 사본이 모두 VFS에 있으므로, 각 행 옆에 단순한 링크 대신 실제 전후 수치를 표시할 수 있습니다:

// Both files are in the VFS, so the saving can be measured
const before = window.dotnetRuntime.Module.FS.readFile(name).length;
const after = window.dotnetRuntime.Module.FS.readFile(out).length;

절약된 비율을 표시하면 버튼이 결과로 바뀝니다. 두 숫자가 거의 같다면 문서의 이미지에서 돌려줄 것이 없었다는 뜻입니다. 그것은 실패가 아니라 정보입니다.


일반적인 문제

출력에 추가 경고 줄이 포함됩니다. 라이선스가 없는 빌드는 문서에 Evaluation Warning : The document was created with Spire.PDF for JavaScript.를 삽입하며, 이는 호출마다 추가됩니다. 한 세션에서 같은 파일을 두 번 변환하면 경고 줄이 두 번 나타납니다. 임시 라이선스는 이를 제거합니다. 30일 키를 원하면 영업팀에 문의하세요. 기능 제한도 해제됩니다.

변환된 문서가 똑같아 보입니다. 문서가 무엇으로 만들어졌는지 확인하세요. 비트맵 없이 텍스트와 벡터 아트로만 되어 있다면 그레이스케일 패스가 바꿀 것이 거의 없으며 차이는 보이지 않습니다. 이는 버그가 아니라 예상된 동작입니다.

첫 클릭에서 아무 일도 일어나지 않습니다. 모듈이 아직 로드 중이었습니다. 모듈 참조에서 핸들러를 보호하거나, 위에서 보여준 것처럼 준비될 때까지 버튼을 비활성화하세요.

파일이 거의 줄지 않았습니다. 그레이스케일 변환은 이미지만 건드립니다. 무게가 글꼴이나 콘텐츠 스트림에 있다면 이 변환은 지렛대가 아닙니다. 위에 링크된 압축 문서를 참조하세요.


자주 묻는 질문

그레이스케일로 변환하면 텍스트를 선택할 수 없게 되나요? 아니요. 텍스트는 래스터화되지 않습니다. 이미지만 다시 인코딩되므로 결과는 여전히 검색, 선택, 복사할 수 있습니다. 단지 색상이 없을 뿐입니다.

일부 페이지만 변환할 수 있나요? 변환기는 문서 전체를 대상으로 작동합니다. 파일의 일부를 컬러로 유지해야 한다면 먼저 문서를 분할하고, 회색으로 만들어야 할 부분을 변환한 다음, 조각들을 다시 병합하세요.

그레이스케일 변환은 항상 파일 크기를 줄여 주나요? 항상은 아니지만 보통 조금 줄어듭니다. 절약은 이미지에서 오므로 비트맵이 많을수록 이득이 커집니다. 이미 텍스트와 벡터로만 된 문서는 거의 변하지 않을 수 있습니다.

파일을 어딘가에 업로드해야 하나요? 아니요. 모든 것이 브라우저에서 이루어집니다. PDF는 가상 파일 시스템에 들어가고, 그곳에서 다시 작성되며, 다운로드를 위해 다시 읽혀 나옵니다. 따라서 기밀 문서는 기기를 떠나지 않습니다.

사용자에게 두 버전을 모두 제공할 수 있나요? 예. ToGrayPdf는 새 파일 이름에 작성하고 입력을 그대로 둡니다. 따라서 같은 세션에서 컬러 원본과 그레이스케일 사본을 모두 사용할 수 있습니다.


참고 항목