패스 하나 — 구조 정리
pdf-lib가 문서를 로드하고 객체 스트림을 활성화한 채로 다시 씁니다. 페이지 썸네일, 고아 객체, 식별 메타데이터가 제거됩니다. 폰트, 이미지, 페이지 콘텐츠는 건드리지 않으므로 이 패스는 사실상 무손실입니다.
워커 큐도, 업로드 엔드포인트도, "서버에서 처리 중"이라는 문구도 없습니다. 드롭부터 다운로드까지 PDF에 정확히 무슨 일이 일어나는지 여기 있습니다.
내 PDF에서 시도1단계
파일은 브라우저의 File.arrayBuffer() API로 읽힙니다. 어디에도 전송되지 않으며, 바이트는 탭의 메모리에만 존재합니다.
PDF.js가 문서를 열고 페이지 수를 셉니다. 파일 전체에 걸쳐 몇 페이지가 샘플링되어 텍스트 밀도를 측정합니다. 샘플링된 페이지에 문자가 거의 없으면 문서는 아마 스캔입니다. 문자가 많으면 텍스트 기반입니다. 이 분류가 이미지 재압축과 래스터화 중 무엇을 먼저 시도할지 결정합니다.
분석은 비밀번호 보호도 잡아냅니다. 암호화된 파일은 손상된 출력을 만들지 않고 명확한 메시지와 함께 여기서 멈춥니다.
2단계
각 패스는 완전한 재구축입니다. 엔진은 다음, 더 파괴적인 패스가 필요한지 결정하기 전에 결과를 측정합니다.
pdf-lib가 문서를 로드하고 객체 스트림을 활성화한 채로 다시 씁니다. 페이지 썸네일, 고아 객체, 식별 메타데이터가 제거됩니다. 폰트, 이미지, 페이지 콘텐츠는 건드리지 않으므로 이 패스는 사실상 무손실입니다.
엔진은 폼 XObject 안에 중첩된 이미지를 포함해 각 페이지의 리소스 딕셔너리를 훑고 JPEG 이미지 스트림을 찾습니다. 각각은 createImageBitmap으로 디코딩되고, 캔버스에 축소된 크기로 그려지며, 더 낮은 품질로 재인코딩됩니다.
새 스트림은 제자리에서 이전 객체를 대체하므로 페이지 레이아웃, 텍스트, 링크, 벡터 아트는 바뀌지 않습니다. 소프트 마스크, CMYK 색 공간, JPX 또는 JBIG2 압축을 가진 이미지는 깨진 렌더링을 피하기 위해 건너뜁니다.
목표가 여전히 닿지 않을 때 — 또는 소스가 스캔일 때 — PDF.js가 각 페이지를 36–160 DPI의 오프스크린 캔버스로 렌더링합니다. JPEG는 pdf-lib로 새 문서에 조립됩니다. 텍스트를 픽셀로 평탄화하므로 마지막에 실행되며 결과 패널이 알려줍니다.
3단계
이미지 설정은 예상 출력 가중치(스케일의 제곱 × JPEG 품질)로 정렬된 사다리를 따라 걷습니다. 목표 미만으로 측정된 첫 번째 단계가 이깁니다. 결과가 목표보다 충분히 아래면 엔진은 한 단계 더 나은 것을 시도해 더 선명한 파일을 주고, 맞는 쪽을 유지합니다.
래스터화는 160 DPI에서 36 DPI까지 별도의 사다리를 사용합니다. 해상도를 낮추는 것이 스캔을 줄이는 가장 빠른 방법이므로, 사다리는 어느 한쪽을 극단으로 떨어뜨리기보다 해상도와 JPEG 품질을 함께 거래합니다.
정직 규칙: 성공은 생성된 파일에서 측정된 outputBytes <= targetBytes를 의미합니다. 맞는 것이 없으면 도구는 가장 작은 실제 결과와 목표를 얼마나 초과하는지 보여줍니다. 내림, 추정, 초과를 성공으로 라벨링하지 않습니다.
4단계
PDF 파싱과 JPEG 인코딩은 전용 워커에서 실행되므로 큰 파일이 처리되는 동안에도 스크롤, 선택, 입력이 반응합니다.
이미지 작업은 DOM에 닿지 않는 오프스크린 캔버스에서 일어납니다. 지원하지 않는 브라우저는 메인 스레드의 청크 단위 경로로 폴백합니다.
페이지는 배치로 처리되고, 비트맵은 사용 후 닫히며, 객체 URL은 해제되고, 큰 파일은 휴대폰 메모리를 고갈시키기 전에 표시됩니다.
할 수 없는 것
압축기가 어떻게 동작하는지에 대한 더 깊은 답.
이미지 품질과 파일 크기의 관계는 선형이 아니고 모든 PDF가 다르기 때문입니다. 엔진은 높은 품질에서 공격적인 압축으로 사다리를 걷고, 각 단계에서 실제 PDF를 저장하고 측정한 뒤, 목표에 맞는 첫 번째 결과에서 멈춥니다. 그 결과는 한도를 충족하는 가장 보기 좋은 파일입니다.
래스터화는 텍스트를 픽셀로 바꿉니다. 파일은 작아지지만 텍스트 선택이 멈추고, 링크가 깨지며, 작은 글씨가 흐려집니다. 스캔을 위한 최후의 수단으로 제공되며, 결과 패널은 항상 사용되었을 때 알려줍니다.
아직 아닙니다. PDF.js는 비밀번호로 암호화된 파일을 열 수 있지만, 문서를 재구축하는 라이브러리는 결과를 다시 암호화할 수 없습니다. 깨진 파일을 만드는 대신 압축기가 암호화를 감지하고 먼저 PDF 리더에서 비밀번호를 제거하라고 요청합니다.
텍스트와 벡터 그래픽은 이미 컴팩트합니다. 파일의 95%가 텍스트와 폰트라면 제거할 중복 데이터가 거의 없습니다. 그런 파일에서 큰 절감을 보고하는 도구는 보통 페이지를 래스터화하고 있으며, 그래서 이 도구는 사용된 방법을 보고합니다.
어떤 수정도 암호화 서명을 무효화합니다. 어떤 압축 도구도 이를 보존할 수 없습니다. 서명된 원본을 보관하고, 공유용으로 복사본을 압축하세요.