본문 바로가기

파일 형식 백과사전

한 장짜리 한글 문서를 PDF로 저장했더니 45KB, 용량의 71%는 폰트였습니다

워드에서 만든 문서를 PDF로 내보냈는데 생각보다 파일이 크게 나오는 경우가 있습니다. 이미지도 없고 페이지도 한 장인데 수십 KB에서 수백 KB가 나오면 어디에서 그 용량이 나온 것인지 감이 잡히지 않습니다.

같은 분량의 영문 문서와 한글 문서를 각각 PDF로 내보내 비교하고, 그 PDF 안을 파이썬으로 열어 무엇이 자리를 차지하는지 바이트 단위로 확인해 봤습니다. 범인은 본문이 아니라 문서에 쓰인 글꼴이었습니다.

 

실측 차트 두 개. 왼쪽은 같은 워드 문서를 PDF로 내보냈을 때 영문 문서 4.8KB에 폰트 임베딩 없음, 한글 문서 44.7KB 중 폰트가 32.0KB로 71퍼센트. 오른쪽은 서로 다른 한글 글자 수가 50자에서 2000자로 늘 때 폰트 몫이 32KB에서 456KB까지 증가

 

PDF에는 글자만 담기는 게 아닙니다

PDF의 목적은 어느 컴퓨터에서 열어도 같은 모양으로 보이는 것입니다. 그런데 받는 사람의 PC에 그 글꼴이 없으면 모양이 무너집니다. 그래서 PDF는 문서에 쓰인 글꼴을 파일 안에 통째로 넣어 두는데, 이것을 폰트 임베딩이라고 부릅니다.

영문 문서라면 이 부담이 작습니다. 알파벳과 기호를 다 합쳐도 글자 종류가 백여 개 수준이고, 표준으로 취급되는 글꼴은 아예 넣지 않고 이름만 적어 두기도 합니다. 한글은 사정이 다릅니다. 완성형 한글만 1만 1천 자가 넘고, 글꼴 파일 자체도 훨씬 무겁습니다.


실제로 열어 보니 71%가 폰트였습니다

윈도우 11에서 Word 2013으로 같은 형식의 보고서를 두 벌 만들었습니다. 하나는 Arial로 쓴 영문, 하나는 맑은 고딕으로 쓴 한글입니다. 둘 다 한 페이지짜리이고, 오히려 영문 쪽 글자 수가 두 배 많습니다.

문서 본문 글자 수 PDF 크기 그중 폰트
영문 (Arial) 685자 4,941 B (4.8 KB) 0 B (임베딩 없음)
한글 (맑은 고딕) 337자 45,809 B (44.7 KB) 32,757 B (32.0 KB)

글자 수는 절반인데 파일은 9배가 됐습니다. 이 값들은 짐작이 아니라 PDF 안에 든 폰트 데이터의 크기를 직접 잰 것입니다. pypdf로 각 페이지의 글꼴 자원을 따라가면 폰트 파일이 통째로 들어 있는 자리를 찾을 수 있습니다.

from pypdf import PdfReader

r = PdfReader("보고서.pdf")
for page in r.pages:
    fonts = page["/Resources"]["/Font"]
    for key in fonts:
        f = fonts[key].get_object()
        for node in [f] + [d.get_object() for d in f.get("/DescendantFonts", [])]:
            desc = node.get("/FontDescriptor")
            if desc and "/FontFile2" in desc.get_object():
                st = desc.get_object()["/FontFile2"].get_object()
                print(node["/BaseFont"], len(st._data), "바이트")

한글 PDF에서 나온 출력은 이렇습니다.

/ABCDEE+맑은 고딕 32757 바이트

44.7KB짜리 파일에서 32.0KB, 그러니까 전체의 71%를 글꼴 하나가 차지하고 있었습니다. 반면 영문 PDF에서는 이 자리가 아예 비어 있었습니다. Arial은 이름만 적혀 있고 폰트 데이터가 들어가지 않았습니다.

 

폰트 이름 앞에 붙은 여섯 글자의 정체

출력에 나온 ABCDEE+맑은 고딕에서 앞의 여섯 글자와 더하기 기호는 서브셋 표시입니다. 폰트를 원본 그대로가 아니라 이 문서에 필요한 만큼만 추려 넣었다는 표시인데, 정확히 무엇을 추려냈는지는 잠시 뒤에 직접 뜯어보겠습니다.

이 서브셋이 없었다면 상황은 훨씬 나빴을 겁니다. 윈도우에 설치된 맑은 고딕 원본 파일은 13,459,196바이트, 약 12.8MB입니다. 이번 문서에 들어간 조각은 압축을 풀어도 223KB로, 원본의 1.7% 수준입니다. 한글 폰트 파일이 왜 그렇게 큰지는 글꼴 하나에 몇 개의 글자가 들어가는지를 따져 본 글에서 다룬 적이 있습니다.

 

글자 몇 개만 남겼는데 왜 223KB일까

여기서 궁금해집니다. 이 문서에 쓴 한글은 60여 종류뿐인데 서브셋이 223KB나 되는 것이 이상합니다. PDF에서 폰트 데이터를 파일로 뽑아내 폰트 분석 도구인 fontTools로 열어 봤습니다.

from fontTools.ttLib import TTFont

sub = TTFont("subset_malgun.ttf")   # PDF에서 뽑아낸 서브셋
org = TTFont(r"C:\Windows\Fonts\malgun.ttf")
print(sub["maxp"].numGlyphs, org["maxp"].numGlyphs)

두 값이 똑같이 28,215로 나왔습니다. 글자 자리 자체는 하나도 줄지 않았다는 뜻입니다. 대신 실제 윤곽선, 그러니까 글자 모양 데이터가 남아 있는 자리를 세어 보니 28,215칸 중 68칸뿐이었습니다. 문서에 쓴 글자 종류와 거의 일치합니다. 나머지 칸은 빈 껍데기로 남아 있습니다.

서브셋 안에서 무엇이 자리를 차지하는지도 표로 확인했습니다.

구성 요소 크기 비중 하는 일
hmtx와 vmtx 124,556 B 54.6% 글자마다의 폭과 높이 값
loca 56,432 B 24.7% 글자 모양이 어디에 있는지 알려주는 색인
glyf 19,068 B 8.4% 실제 글자 모양

정작 글자 모양은 8.4%뿐이고, 글자 하나하나의 폭을 적어 둔 표와 위치 색인이 79%를 차지했습니다. 한글 폰트는 글자 수가 많아 이 명단이 길 수밖에 없고, 그래서 실제로 쓴 글자가 몇 개든 명단은 통째로 따라옵니다. 원본에서 13MB를 차지하던 글자 모양 데이터가 19KB로 줄어든 것에 비하면, 줄지 않는 쪽이 발목을 잡는 셈입니다.


용량을 결정하는 것은 문서 길이가 아닙니다

서브셋 방식이라는 것은, 문서를 아무리 길게 써도 같은 글자를 반복해서 쓰면 폰트 크기는 늘지 않는다는 뜻이기도 합니다. 실제로 늘어나는 조건은 두 가지였습니다.

첫째, 서로 다른 글자를 많이 쓸수록 커집니다. 서로 다른 한글 글자를 50자, 200자, 500자, 1000자, 2000자로 늘려가며 같은 방식으로 PDF를 만들어 폰트 몫만 재 봤습니다.

서로 다른 글자 수 PDF 전체 폰트가 차지한 크기
50자 36.8 KB 32.4 KB
200자 74.5 KB 68.2 KB
500자 153.3 KB 143.6 KB
1,000자 264.7 KB 249.4 KB
2,000자 482.3 KB 455.6 KB

둘째, 문서에 쓴 글꼴 종류가 늘면 그만큼 통째로 더 들어갑니다. 본문을 304자로 고정한 채 문단마다 다른 글꼴을 지정해 봤습니다.

쓴 글꼴 PDF 크기 폰트 몫
맑은 고딕 1종 98.2 KB 90.5 KB
맑은 고딕, 굴림 2종 111.1 KB 101.6 KB
맑은 고딕, 굴림, 바탕 3종 143.0 KB 131.8 KB

내용은 한 글자도 늘지 않았는데 글꼴을 두 개 더 썼다는 이유만으로 파일이 1.5배가 됐습니다. 제목은 이 글꼴, 본문은 저 글꼴, 강조는 또 다른 글꼴로 섞어 쓴 자료가 유독 무거운 이유가 여기 있습니다.

PDF 용량을 줄이고 싶다면 문장을 덜어내기 전에 글꼴 종류부터 세어 보시는 편이 빠릅니다.

 

자주 묻는 질문

Q. 워드의 '파일에 글꼴 포함' 옵션을 끄면 PDF가 작아지나요?
아닙니다. 그 옵션은 docx 파일에 글꼴을 넣는 설정이라 PDF와는 상관이 없습니다. 실제로 켜고 껐을 때를 비교해 보니 docx는 12.1KB에서 104.0KB로 8배 넘게 커졌지만, 같은 문서로 내보낸 PDF는 양쪽 모두 100,216바이트로 1바이트도 다르지 않았습니다.

Q. PDF로 저장할 때 나오는 '최소 크기' 옵션은요?
이번 문서에서는 표준 옵션과 최소 크기 옵션의 결과가 100,216바이트로 완전히 같았습니다. 이 옵션은 주로 이미지 해상도를 낮춰 용량을 줄이는 쪽이라, 글자만 있는 문서에서는 줄일 여지가 없었던 것으로 보입니다. 사진이 많이 들어간 문서라면 결과가 다를 수 있습니다.

Q. 폰트를 안 넣으면 더 작아질 텐데 왜 넣나요?
받는 사람 PC에 그 글꼴이 없을 때를 대비한 것입니다. 임베딩된 PDF는 어디서 열어도 줄바꿈과 자간까지 그대로 유지됩니다. 인쇄소에 넘기는 파일이라면 이 부분을 빼면 안 됩니다. 다만 글꼴에 따라 문서에 끼워 넣는 것을 제한해 둔 경우가 있어, 배포용 문서라면 그 값을 미리 확인해 두는 편이 안전합니다.

Q. 이미 있는 PDF가 왜 큰지 확인하려면요?
위 코드를 그대로 돌려 보면 폰트가 차지하는 몫이 바로 나옵니다. 폰트 몫이 작은데도 파일이 크다면 원인은 다른 곳, 대개 이미지나 스캔본입니다. 스캔한 PDF가 줄지 않는 문제는 성격이 달라 따로 다룬 적이 있습니다.

 

정리하면 한글 문서의 PDF 용량은 페이지 수보다 글꼴 쪽에 훨씬 민감합니다. 오늘 만들 자료가 있다면 제목과 본문에 쓰는 글꼴을 한두 종류로 맞춰 보세요. 같은 내용으로도 파일이 눈에 띄게 가벼워집니다.

 

본문의 모든 용량은 Word 2013으로 문서를 만들어 PDF로 내보낸 뒤, pypdf로 폰트 스트림 크기를 직접 읽어 얻은 값입니다.

 

 

 

움짤(GIF) 용량이 유독 커요, 프레임과 색상 수로 줄이는 법

사진 몇 장을 이어 붙여 움짤을 만들었는데, 정지 사진 하나보다 용량이 몇 배나 커진 경험 있으신가요. 카카오톡으로 보내려니 전송이 느리고, 커뮤니티에 올리려니 용량 제한에 걸리기도 합니

richyeon.com

 

 

여러 개의 PDF를 하나로 합치고, 필요한 페이지만 빼내는 법

계약서, 영수증, 신분증 사본을 따로따로 스캔해 두었다가 한 파일로 제출해야 할 때가 있습니다. 반대로 여러 장짜리 PDF에서 딱 두 장만 보내야 할 때도 있고요.PDF는 워드처럼 열어서 이어 붙이

richyeon.com

 

 

파일 이름 뒤 .jpg를 .png로 바꾸면 진짜 변환될까, 흔한 오해와 실제

이미지가 PNG여야 한다고 해서, 파일 이름 끝의 .jpg를 지우고 .png로 바꿔 본 적 있으신가요. 겉보기엔 아이콘도 바뀌고 그럴듯해 보입니다.그런데 어떤 사이트에 올리면 "형식이 맞지 않는다"며

richyeon.com