PDF 압축했더니 텍스트가 사라졌다 — 압축률이 아니라 방식의 문제였다
지난주에 7.28 MB짜리 스캔 리포트를 560 KB로 압축했다. 용량은 잘 줄었길래 만족했는데, Ctrl+F로 본문을 검색하니 아무것도 안 나왔다. 한 단어도.
처음엔 압축을 너무 세게 걸었나 싶어서 설정을 두 단계 낮춰봤다. 결과는 똑같았다. 압축률의 문제가 아니었다.
같은 이름으로 불리는 두 가지 다른 작업
페이지 전체 래스터화
각 페이지를 이미지로 렌더링한 뒤, 그 이미지들을 새 PDF로 묶는다. 구현이 간단하고 숫자도 잘 나온다. 대신 텍스트 레이어, 벡터, 링크, 북마크가 전부 사라진다. 결과물은 문서가 아니라 이미지 모음이다.
구조를 유지한 재인코딩
PDF 객체 구조를 파싱해서 내장된 래스터 이미지만 한 장씩 다시 인코딩한다. 텍스트, 벡터, 폰트, 링크는 그대로 남는다.
용량 감소폭은 비슷하게 나온다. 하지만 남는 결과물이 완전히 다르다.
용량은 대체 어디에 있나
텍스트와 벡터 그래픽 자체는 아주 작다. 폰트도 수십에서 수백 KB 수준이다. PDF를 메가바이트 단위로 만드는 건 거의 항상 내장 비트맵이다. 스캔본, 사진, 스크린샷 같은 것들.
그래서 이미지만 건드려도 나머지를 망가뜨리지 않고 비슷한 감소폭을 얻을 수 있다.
실효 DPI — 이 이미지를 줄여도 되는가
모든 내장 이미지를 다운샘플링할 필요는 없다. 판단 기준은 실효 DPI, 즉 이미지의 픽셀 수를 페이지에서 실제로 차지하는 물리적 크기로 나눈 값이다.
같은 2400px 폭 이미지라도 A4 한 면을 꽉 채울 때와 구석에 작게 들어갈 때 필요한 해상도가 전혀 다르다.
4페이지 리포트로 확인해보니 실효 DPI가 359×452로 나왔다.
숫자가 두 개다. 가로 359, 세로 452. 이미지가 비균등 배율로 배치될 수 있어서 두 축의 실효 DPI가 원래 다르다. 한쪽 축만 보고 판단하면 과하게 줄이거나, 쓸모없는 픽셀을 그대로 남기게 된다.
이 부분은 나도 처음엔 표시 오류인 줄 알았다.
프리셋 4개 실측
같은 파일(7.28 MB / 4페이지)로 네 가지를 다 돌려봤다.
| 프리셋 | 결과 | 감소율 | 이미지 재인코딩 | 다운샘플 |
|---|---|---|---|---|
| 화면·메일 72 dpi | **98 KB** | −98.7% | 4/4장 | 481×255 · q82 |
| 전자책 150 dpi | **560 KB** | −92.5% | 4/4장 | 1003×531 · q88 |
| 인쇄 300 dpi | 3.08 MB | −57.7% | 4/4장 | 2400×1062 · q92 |
| 무손실(구조만) | 7.27 MB | −0.1% | **0/4장** | 변경 없음 |마지막 줄이 흥미롭다. 이미지를 한 장도 재인코딩하지 않았는데 용량은 거의 그대로다. 그런데도 미사용 리소스 4건을 회수하고 구조 스트림 4개를 재압축했다.
구조 최적화와 이미지 다운샘플링은 별개의 작업이고, 앞엣것은 언제나 무손실이다.
안 망가졌다는 걸 어떻게 확인하나
용량이 줄었다는 것만으로는 아무것도 알 수 없다. 세 개의 결과물을 PDF 파서로 다시 읽어서 확인했다.
| | 원본 | 72 dpi | 150 dpi | 300 dpi |
|---|---|---|---|---|
| 페이지 수 | 4 | 4 ✓ | 4 ✓ | 4 ✓ |
| 추출 가능 텍스트 | 2723자 | **2723** ✓ | **2723** ✓ | **2723** ✓ |
| 링크 주석 | 4개 | 4 ✓ | 4 ✓ | 4 ✓ |
| MediaBox | 595.3×841.9 | 동일 ✓ | 동일 ✓ | 동일 ✓ |원본의 1.3%까지 줄어든 프리셋에서도 텍스트는 한 글자도 빠지지 않았다.
처리 파이프라인의 마지막 단계 자체가 검증이다. 구조 파싱 → 내장 이미지 재인코딩 → 객체 회수 및 기록 → 페이지 되읽기 검증. 내가 밖에서 한 확인과 같은 작업이다.
안 되는 경우들
텍스트만 있는 PDF는 거의 안 줄어든다. 6페이지 텍스트 문서는 37 KB에서 33 KB(−11%)였다. 내장 이미지가 0장이면 재인코딩할 대상이 없다. 계약서나 논문에는 기대하기 어렵다.
암호화된 PDF는 보호를 먼저 해제해야 한다.
전자서명이 있는 PDF는 다시 쓰는 순간 서명이 무효가 된다. 구조적인 제약이라 도구를 바꿔도 마찬가지다.
일부 이미지 포맷은 그대로 유지된다: JPEG 2000, JBIG2, CCITT FAX, CMYK 인쇄용 JPEG 등. 브라우저에서 동등하게 재인코딩할 수 없어서 건드리지 않는 쪽을 택한다.
보내기 전 3초 확인
광고하는 압축률 말고, 이 세 가지만 해보면 된다.
본문의 단어 하나를 검색해본다
링크를 클릭해본다
페이지 수를 확인한다
셋 다 멀쩡하면 압축이 된 것이고, 하나라도 빠졌으면 압축이 아니라 열화다.
이해관계 고지: 본문에서 사용한 ImgIng(imging.ai)의 PDF 압축 기능 개발에 참여하고 있습니다. 처리는 전부 브라우저 안에서 끝나고 파일은 업로드되지 않습니다. 위의 수치는 모두 글을 쓰면서 실측한 것이고, 검증 방법도 본문에 적어두었습니다.
