고스트스크립트·MuPDF에 브로틀리(Brotli) 압축 추가 — PyMuPDF 쓰시는 분들도 참고하세요

,
  • 고스트스크립트(Ghostscript) — 포스트스크립트·PDF 문서를 해석하고 렌더링하는 범용 처리 엔진입니다. 인쇄, 이미지 변환, 장기 보관용 PDF/A 변환처럼 눈에 잘 띄지 않는 곳에서 작동합니다.

  • MuPDF — 초경량·초고속을 강점으로 내세우는 PDF 렌더링 엔진입니다. PDF 뷰어를 앱에 내장하거나 텍스트·이미지를 뽑아내는 데 널리 쓰이는데, 이걸 Python에서 쓸 수 있게 해주는 바인딩이 바로 PyMuPDF(fitz)입니다. RAG나 문서 임베딩 파이프라인에서 LangChain의 PyMuPDFLoader나 pymupdf4llm 패키지로 접해보신 분들 많으실 것 같아요.

이 두 엔진에 최근 브로틀리(Brotli) 압축 지원이 함께 추가됐다는 소식을 공유합니다. 브로틀리는 원래 구글이 웹 압축용으로 만든 알고리즘인데, 같은 품질을 유지하면서도 Flate(zlib)보다 파일을 더 작게 압축할 수 있다는 장점이 있습니다.
대량의 PDF를 쌓아두고 처리하는 데이터 파이프라인이라면, 파일 하나하나의 압축률보다 전체 저장 공간·비용이 중요한 경우가 많잖아요. 이번 발표에서도 "진짜 가치는 파일 한 개가 아니라 수백만~수십억 건 단위로 쌓인 문서 컬렉션 전체에서 나온다"는 점을 강조하고 있습니다.

얼마나 줄어드는지?

  • Adobe PDF 1.7 레퍼런스 매뉴얼(1,310페이지, 30.95MB) → 브로틀리 적용 후 13MB 남짓
  • 텍스트·벡터 위주의 흑백 문서는 용량이 절반 정도까지 감소

다만 아직 모든 PDF 도구·뷰어가 브로틀리를 지원하는 건 아니라서, 여러 환경에서의 호환성이 중요하다면 조금 지켜보는 게 낫고, 저장 공간 절감이 더 급하다면 지금부터 써봐도 좋을 것 같습니다. 읽는 건 문제없고(기존 뷰어에서 별도 설정 없이 열립니다), 새로 만들 때만 아래처럼 옵션을 켜주면 됩니다.

  • MuPDF: 1.26.0부터 (2025년 5월)
  • Ghostscript: 10.06.0부터 (2025년 9월)

MuPDF 코어 엔진에서

이미 만들어둔 PDF를 재압축하고 싶다면 MuPDF에 딸려오는 mutool CLI로 바로 할 수 있습니다.

mutool clean -dizzZ -e75 input.pdf output.pdf

d(압축 해제) → zz(브로틀리로 재압축) → Z(오브젝트 스트림 사용) → e(압축 강도, 40~100) 순서예요. 강도는 대략 40이 기본 Flate랑 속도 비슷하면서 결과가 더 좋고, 75는 최대 Flate 속도에 압축 품질만 좋아지고, 100은 시간은 오래 걸려도 압축률이 최대치라고 보시면 됩니다.

압축에 시간이 얼마나 걸리든 압축을 푸는(디코딩) 속도는 항상 동일하게 빠르다고 하니, 이 명령어로 브로틀리가 우리 워크플로우에 도움이 될지 가볍게 테스트해보기 좋습니다. C API에서는 pdf_write_options의 do_compress를 2로 설정하면 됩니다.

MuPDF 코어를 직접 쓰지 않고 언어별 바인딩을 쓰시는 분들은 아래처럼 동일한 옵션을 그대로 쓰면 됩니다.

PyMuPDF (Python 바인딩)

import pymupdf

doc = pymupdf.open("input.pdf")
doc.save(
    "output.pdf",
    use_objstms=True,        # 오브젝트를 압축 가능한 스트림으로 묶기
    deflate=2,                # 브로틀리 압축 요청
    compression_effort=100,   # 브로틀리가 최대한 압축하도록 지정
)
doc.close()
  • use_objstms — 오브젝트를 압축 가능한 스트림으로 묶어줍니다
  • deflate=2 — 압축 알고리즘으로 브로틀리를 사용하도록 지정합니다
  • compression_effort — 압축 강도(1~100)

using MuPDF.NET;

Document doc = MuPDF.NET.Document.Open("input.pdf");
doc.Save("output.pdf", useObjstms: 1, deflate: 2, compressionEffort: 100);
doc.Close();

Ghostscript는

pdfwrite로 PDF 만드실 때 -dUseBrotli 플래그만 추가하면 됩니다.

gs -o output.pdf -sDEVICE=pdfwrite -dUseBrotli input.pdf

압축 강도를 세밀하게 조절하는 옵션은 아직 없고, 2026년 9월 출시 예정인 v10.08.0부터 -dStreamEffort(브로틀리 1~11, Flate 1~9)로 조절 가능해질 예정이라고 합니다.


PDF에서 텍스트/이미지 뽑아서 임베딩하는 파이프라인을 돌리다 보면 저장 용량이 은근히 신경 쓰이죠. 같은 고민을 가지신 분들에게는 반가운 소식일 듯 합니다.

참고로, 위에 설명 드린 PyMuPDF의 명령어는 상용 버전의 문서 데이터 추출 및 가공 라이브러리 PyMuPDF Pro에서도 동일하게 동작합니다!

참고 링크