AI 해결 노트 · 2026-09-18 · 실측 2026-09-18
PDF 용량 줄이기 — 사진 많은 문서는 40분의 1, 글자 문서는 거의 안 줄어듭니다
한 줄로
37.5MB짜리 사진 문서와 74KB짜리 글자 문서를 놓고 용량을 줄여 봤습니다. 사진 문서는 그림을 다시 저장하는 것만으로 3.7MB(10.0%)까지, 해상도를 반으로 낮추면 0.9MB(2.5%)까지 내려갔습니다. 글자 문서는 시험한 방법 가운데 가장 잘 줄인 것이 95.4%였고, 옵션 하나(clean=True)만 켜면 오히려 182%로 커졌습니다. 외부 프로그램은 하나도 깔지 않았습니다.
이런 분께
- 메일 첨부 용량 제한에 걸려 PDF를 줄여야 하는 분
- 압축했는데 하나도 안 줄어서 방법이 잘못된 건가 싶은 분
- 회사 자료라 압축 사이트에 올리기 어려운 분
실측 환경
| 항목 | 값 |
|---|---|
| OS | Windows 11 Home 25H2 (10.0.26200.9457) |
| 셸 | PowerShell 7 / Git Bash |
| 엣지 | 153.0.4234.32 |
| Python | 3.12.10 |
| 파이썬 꾸러미 | PyMuPDF 1.28.0, Pillow, NumPy |
| 외부 프로그램 | 깔지 않았습니다 (Ghostscript 등 없음) |
| 시험 파일 | 시험용으로 만든 더미 PDF 두 개. 사진은 프로그램으로 그려 낸 무늬입니다 |
시험에 쓴 문서 두 개
용량 이야기는 문서가 어떤 것이냐에 따라 답이 완전히 갈립니다. 그래서 두 가지를 만들었습니다.
| 문서 | 쪽 수 | 크기 | 안에 든 것 |
|---|---|---|---|
| ① 사진이 많은 문서 | 6 | 39,305,252바이트 (37.5MB) | 그림 12장, 글자 72자 |
| ② 글자 위주 문서 | 12 | 74,157바이트 (0.07MB) | 그림 0장, 글자 13,359자 |

사진 문서의 1쪽 첫 그림은 1500x1000픽셀 PNG입니다. 쪽에 놓인 자리가 가로 495pt(약 17.5cm)이니 218dpi로 들어가 있는 셈입니다. 그림 한 장이 3,816,210바이트를 차지합니다.
잰 것은 셋입니다. 파일 크기, 글자를 여전히 뽑을 수 있는지, 그리고 확대했을 때 얼마나 뭉개지는지. 마지막 것은 결과 파일과 원본 파일의 1쪽을 각각 200dpi로 그린 뒤 픽셀 값(0~255)의 절대 차이를 평균 낸 값입니다. 아래 표에서 「화질 차이」라고 쓴 것이 이 값이고, 0이면 원본을 그린 것과 같습니다.
크기를 MB로 적은 곳은 1MB를 1,048,576바이트로 셈한 값입니다. 정확한 값은 바이트 쪽을 보시면 됩니다.
먼저 알아 둘 것 — 저장 옵션만으로는 안 줄어듭니다
PyMuPDF의 save에 있는 정리 옵션을 하나씩, 그리고 겹쳐서 걸어 봤습니다. 이름만 보면 garbage는 쓸모없어진 덩어리 치우기, deflate는 압축, clean은 내부 구조 정리입니다.
import fitz
d = fitz.open(r"C:\경로\원본.pdf")
d.save(r"C:\경로\결과.pdf", garbage=4, deflate=True, clean=True)
d.close()사진 문서(39,305,252바이트)에 걸어 본 결과입니다.
| 저장 방법 | 결과 크기 | 원본 대비 |
|---|---|---|
garbage=4 | 39,305,252바이트 | 100.0% |
deflate=True | 39,305,252바이트 | 100.0% |
clean=True | 39,306,909바이트 | 100.0% |
garbage=4, deflate=True, clean=True | 39,304,874바이트 | 100.0% |
위에 deflate_images=True 추가 | 39,304,874바이트 | 100.0% |
위에 use_objstms=1 추가 | 39,301,917바이트 | 100.0% |
ez_save() | 39,301,959바이트 | 100.0% |
가장 많이 줄인 것이 3,335바이트, 0.01%입니다. 모두 0.1~0.2초에 끝났습니다. 어느 경우에도 그림은 12개 그대로, 첫 그림도 1500x1000픽셀 그대로였고 화질 차이는 전부 0.00이었습니다. 이 문서에서 무게를 지고 있는 것이 그림인데, 시험한 저장 옵션은 그림을 그대로 둡니다.
사진이 많은 문서 — 그림을 다시 저장하면 됩니다
PyMuPDF에 그림만 골라 다시 저장하는 rewrite_images가 있습니다. 이름대로라면 dpi_threshold는 손댈 그림을 고르는 기준, dpi_target은 낮출 목표, quality는 JPEG 품질입니다. 실제로 몇 픽셀이 나왔는지는 아래 표에 그대로 적었습니다.
import fitz
d = fitz.open(r"C:\경로\원본.pdf")
d.rewrite_images(dpi_threshold=101, dpi_target=96, quality=70)
d.save(r"C:\경로\결과.pdf", garbage=4, deflate=True, clean=True)
d.close()| 설정 | 결과 크기 | 원본 대비 | 그림 크기 | 쪽 위 해상도 | 화질 차이 |
|---|---|---|---|---|---|
| 손대기 전 | 39,305,252바이트 | 100.0% | 1500x1000 PNG | 218dpi | 0.00 |
| threshold 151 / target 150 / q 80 | 3,915,066바이트 | 10.0% | 1500x1000 JPEG | 218dpi | 1.83 |
| threshold 151 / target 110 / q 75 | 3,325,472바이트 | 8.5% | 1500x1000 JPEG | 218dpi | 1.91 |
| threshold 101 / target 96 / q 70 | 964,328바이트 | 2.5% | 750x500 JPEG | 109dpi | 2.50 |
| threshold 101 / target 72 / q 60 | 836,249바이트 | 2.1% | 750x500 JPEG | 109dpi | 2.70 |
걸린 시간은 네 번 모두 2초 안쪽이었습니다(로그에 0.6~1.5초).
가장 크게 줄여 준 것은 해상도가 아니라 그림 형식이었습니다. 1500x1000 픽셀 그대로인데도 PNG가 JPEG로 바뀌면서 그림 한 장이 3,816,210바이트에서 364,280바이트로 내려갔습니다. 파일 전체로는 10분의 1입니다. 여기서 해상도까지 반으로 낮추면 2.5%까지 갑니다.
픽셀 수가 1500에서 750으로 딱 절반이 된 것이 눈에 띕니다. target을 110으로 주든 150으로 주든 1500 그대로였고, threshold 101 / target 96으로 내리자 한 번에 750이 됐습니다. 적어 준 dpi에 그대로 맞춰 주지는 않았습니다. 어느 설정에서 몇 픽셀이 되는지는 결과를 뜯어 보고 정하시는 편이 확실합니다.
확대해서 화질을 봤습니다. 같은 자리를 400%로 늘린 것입니다.

원본과 target=150, quality=80은 원 테두리가 매끈합니다. target=96부터 테두리에 계단이 보이고 무늬가 뭉개지기 시작하며, target=72는 더 흐립니다. 도면이나 작은 글씨가 찍힌 사진이라면 96 앞에서 멈추시는 편이 안전합니다.
뽑히는 글자는 어느 설정에서도 72자 그대로였습니다.

글자 위주 문서 — 줄일 것이 거의 없습니다
같은 옵션을 12쪽짜리 글자 문서(74,157바이트)에 걸었습니다. 이 표에서 가장 잘 줄인 ez_save()는 이렇게 부릅니다.
import fitz
d = fitz.open(r"C:\경로\원본.pdf")
d.ez_save(r"C:\경로\결과.pdf")
d.close()| 저장 방법 | 결과 크기 | 원본 대비 |
|---|---|---|
garbage=4 | 74,156바이트 | 100.0% |
deflate=True | 74,157바이트 | 100.0% |
clean=True | 135,202바이트 | 182.3% |
garbage=4, deflate=True, clean=True | 77,034바이트 | 103.9% |
위에 use_objstms=1 추가 | 73,549바이트 | 99.2% |
ez_save() | 70,712바이트 | 95.4% |
subset_fonts() 뒤 garbage=4, deflate, clean | 77,033바이트 | 103.9% |
rewrite_images(threshold=97, target=96, quality=70) | 77,139바이트 | 104.0% |
가장 잘 줄인 ez_save()가 4.6% 감소입니다. 그리고 clean=True만 켜면 파일이 135,202바이트, 곧 1.8배가 됩니다. 압축하려고 켰다가 오히려 키우는 자리입니다. 왜 커지는지까지는 뜯어보지 않았습니다. garbage=4, deflate=True를 같이 준 경우는 77,034바이트로, 적어도 1.8배까지 가지는 않았습니다.
그림이 없는 문서에 rewrite_images를 걸어도 소용이 없습니다. 104.0%, 곧 줄이는 대신 조금 늘었습니다. 글자 13,359자는 어느 경우에도 그대로 뽑혔습니다.
이 74,157바이트 안에 무엇이 들었는지 세어 봤습니다. 압축된 덩어리(스트림)가 15개인데, 그중 가장 큰 두 개가 글자와 유니코드를 잇는 대응표(50,346바이트)와 한글 글꼴(15,619바이트)입니다. 둘을 더하면 65,965바이트, 파일의 89.0%입니다. 나머지 13개를 다 더해도 1,290바이트이고, 그 안의 글 내용 덩어리에는 이미 FlateDecode가 걸려 있습니다. 글꼴을 빼면 글자가 안 보이니 줄일 거리가 없습니다. 쪽 빼내기 글에서 쪽을 빼도 크기가 안 줄던 것도 같은 덩어리 때문으로 보입니다.
프로그램을 안 깔고 줄이는 길 — 엣지 인쇄
파이썬이 없어도 되는 방법이 하나 있습니다. 사진 문서를 엣지에서 열고 Ctrl+P, 프린터를 「Microsoft Print to PDF」로 골라 인쇄하면 새 PDF가 만들어집니다.
| 항목 | 원본 | rewrite_images (150/q80) | 엣지 인쇄 |
|---|---|---|---|
| 크기 | 39,305,252바이트 | 3,915,066바이트 (10.0%) | 1,641,339바이트 (4.2%) |
| 쪽 수 | 6 | 6 | 6 |
| 그림 | 1500x1000 PNG 218dpi | 1500x1000 JPEG 218dpi | 1500x1000 JPEG 218dpi |
| 뽑히는 글자 | 72자 | 72자 | 0자 |
| 화질 차이 | 0.00 | 1.83 | 3.38 |
| 쪽 크기 | 595.0000 x 842.0000pt | 595.0000 x 842.0000pt | 595.3200 x 841.9200pt |
이 세 파일 중에서는 엣지 인쇄본이 가장 작습니다. 대신 뽑히는 글자가 0자가 됩니다. 여섯 쪽 모두 글자 0자, 그림 2개, 선·면 그림 8개였습니다. 사진 대장처럼 원래 글자가 거의 없는 문서라면 쓸 만하고, 본문이 있는 보고서라면 잃는 것이 큽니다. 다만 해상도를 낮춘 target=96 쪽(964,328바이트)이 더 작으니, 파이썬을 쓸 수 있다면 굳이 이 길로 가실 것은 없습니다.
얼마나 줄었나 — 한눈에
| 문서 | 방법 | 전 | 후 | 줄어든 비율 |
|---|---|---|---|---|
| 사진 6쪽 | 저장 옵션만 | 37.5MB | 37.5MB | 0.01% |
| 사진 6쪽 | 그림을 JPEG로 (q80, 해상도 유지) | 37.5MB | 3.7MB | 90.0% |
| 사진 6쪽 | 그림을 JPEG로 + 해상도 절반 (q70) | 37.5MB | 0.9MB | 97.5% |
| 사진 6쪽 | 엣지 인쇄 | 37.5MB | 1.6MB | 95.8% (뽑히는 글자 0자) |
| 글자 12쪽 | ez_save() | 74,157바이트 | 70,712바이트 | 4.6% |
| 글자 12쪽 | clean=True 만 | 74,157바이트 | 135,202바이트 | 82.3% 늘어남 |
정리하면 이렇습니다. 이번 시험에서 사진 문서는 크게 줄었고, 글자 문서는 가장 잘 줄여야 4.6%였습니다. 손에 든 파일이 어느 쪽에 가까운지는 열어서 사진이 있는지 보시면 대충 갈립니다. 글자뿐인 문서인데 용량이 문제라면 쪽을 덜어 내거나 파일을 나누는 쪽을 먼저 보시는 편이 빠릅니다.
실패한 것
rewrite_images(dpi_threshold=96, dpi_target=96, ...)처럼 두 값을 같게 주면 멈춥니다.
>>> d.rewrite_images(dpi_threshold=96, dpi_target=96, quality=70)
ValueError: {dpi_target=} must be less than {dpi_threshold=} dpi_target이 dpi_threshold보다 작아야 한다는 뜻입니다. 이 글의 표는 threshold를 target보다 높게 잡아 다시 돌린 결과입니다(151/150, 151/110, 101/96, 101/72).
- 엣지 인쇄본은 쪽 크기가 595.3200 x 841.9200pt라 원본 렌더와 픽셀 수가 맞지 않아 화질 차이가 계산되지 않았습니다. 표에 적은 3.38은 렌더 크기를 원본과 같은 1653x2339로 맞춘 뒤 다시 잰 값입니다.
- 사진 문서의 원본 그림이 PNG라 JPEG로 바꾸는 것만으로 10분의 1이 됐습니다. 원본이 이미 JPEG인 문서에서 얼마나 줄어드는지는 이 시험으로 알 수 없습니다. 이 결과만으로 「PDF는 대개 10분의 1로 줄어든다」고 읽으시면 안 됩니다.
확인하지 않은 것
- 원본 그림이 이미 JPEG인 PDF에서 같은 방법을 걸면 얼마나 줄어드는지는 재지 않았습니다. 이번 감소 폭의 상당 부분이 PNG를 JPEG로 바꾼 데서 나왔으므로, 그런 파일에서는 몫이 달라집니다.
- 흑백 스캔본(1비트 그림)은 시험하지 않았습니다.
rewrite_images에는bitonal·gray·set_to_gray같은 값도 있는데 기본값 그대로 뒀습니다. - Ghostscript, Acrobat 같은 외부 프로그램은 깔지 않았습니다. 그쪽이 얼마나 줄이는지는 이 글에서 말할 수 없습니다.
- 엣지 인쇄본에서 글자가 왜 안 뽑히는지는 캐지 않았습니다. 한글이라서 그런 것인지 영문도 같은지 시험하지 않았습니다.
- 인쇄소에 넘길 때 필요한 색 설정이나 글꼴 포함 여부가 이 방법들로 어떻게 되는지는 보지 않았습니다.
- 화질 차이 값은 1쪽을 200dpi로 그린 그림을 픽셀끼리 견준 것입니다. 종이에 뽑았을 때 어떻게 보이는지, 다른 쪽에서도 같은 값이 나오는지는 확인하지 않았습니다.