스크린샷이나 사진을 PNG로 저장해 두면 한 장에 1MB를 훌쩍 넘기는 경우가 흔합니다. 메일에 첨부하거나 블로그에 올릴 때 무거워서, JPG로 바꾸면 가벼워진다는 말을 듣고 변환을 떠올리게 됩니다.
그런데 JPG로 바꾼다고 항상 작아지지는 않습니다. 같은 변환인데 어떤 그림은 5분의 1로 줄고, 어떤 그림은 오히려 5배 넘게 불어납니다. 그 갈림길이 어디인지, 두 종류 이미지를 실제로 만들어 저장해 본 용량으로 보여 드리겠습니다.
사진형과 그래픽형, 두 장을 만들어 쟀습니다
측정 환경은 윈도우 11, 파이썬 3.14.3, 이미지 라이브러리 Pillow 12.2.0입니다. 800x600 크기로 두 종류를 만들었습니다. 하나는 색이 미세하게 다 다른 사진형(그라데이션에 잡음을 섞은 그림), 다른 하나는 같은 색 면적이 넓은 그래픽형(스크린샷처럼 단색 박스 몇 개)입니다.
| 이미지 | PNG | JPG (품질 90) | JPG (품질 75) |
|---|---|---|---|
| 사진형 | 약 1167.7 KB | 약 214.2 KB | 약 106.3 KB |
| 그래픽형 | 약 2.8 KB | 약 16.6 KB | 약 14.6 KB |
방향이 정반대입니다. 사진형은 JPG로 바꾸면 품질 90에서 약 5.5배, 품질 75에서 약 11배까지 가벼워집니다. 그런데 그래픽형은 PNG가 2.8KB인데 JPG로 바꾸면 14KB가 넘어, 오히려 5배 넘게 커집니다.
왜 그림 종류에 따라 갈릴까
두 형식의 압축 방식이 노리는 그림이 다르기 때문입니다. JPG는 사람 눈이 잘 못 느끼는 미세한 차이를 버리는 손실 압축이라, 색이 끝없이 변하는 사진에서 자리를 크게 줄입니다.
반면 PNG는 같은 색이 연달아 나오면 "이 색 몇 칸"처럼 묶어 줄이는 무손실 압축입니다. 단색 박스가 넓은 그래픽이나 스크린샷에서는 이 방식이 매우 효율적입니다.
그래픽형이 JPG에서 커지는 이유는 한 가지 더 있습니다. JPG는 단색 경계에 없던 얼룩(노이즈)을 만들어 내는데, 이 얼룩이 데이터를 늘립니다. 정리하면 색이 다채로운 사진은 JPG, 단색 면이 넓은 그래픽은 PNG가 더 작습니다.
투명 배경은 변환하면 사라집니다
로고처럼 배경이 비치는 PNG를 JPG로 바꿀 때 주의할 점이 있습니다. JPG는 투명도(알파 채널)를 담지 못합니다. 실제로 투명 배경 로고를 변환해 모드를 확인해 봤습니다.
logo.png 모드 : RGBA (투명 정보 있음, 870 byte)
logo.jpg 모드 : RGB (투명 정보 없음, 4793 byte)
변환 후 모드가 RGBA에서 RGB로 바뀌었습니다. 투명했던 부분은 보통 흰색이나 검은색으로 메워집니다. 게다가 이 작은 로고는 JPG로 바꾸면서 용량까지 5배 넘게 늘었습니다. 투명 배경이 필요한 이미지는 JPG 변환 대상이 아닙니다.
직접 변환하고 크기를 확인하는 코드
아래 파이썬 코드는 위 두 종류 이미지를 만들고 PNG와 JPG로 저장해 각 용량을 출력합니다. 설치는 Pillow 하나만 필요합니다(pip install pillow).
import os, random
from PIL import Image
random.seed(42)
W, H = 800, 600
# 사진형: 그라데이션 + 잡음
photo = Image.new("RGB", (W, H))
p = photo.load()
for y in range(H):
for x in range(W):
r = min(255, max(0, int(x/W*255) + random.randint(-30, 30)))
g = min(255, max(0, int(y/H*255) + random.randint(-30, 30)))
b = min(255, max(0, int((x+y)/(W+H)*255) + random.randint(-30, 30)))
p[x, y] = (r, g, b)
photo.save("photo.png")
photo.save("photo_q75.jpg", quality=75)
# 그래픽형: 단색 박스
graphic = Image.new("RGB", (W, H), (245, 245, 245))
g = graphic.load()
for yy in range(150, 450):
for xx in range(50, 350):
g[xx, yy] = (46, 125, 50)
graphic.save("graphic.png")
graphic.save("graphic_q75.jpg", quality=75)
for f in ["photo.png", "photo_q75.jpg", "graphic.png", "graphic_q75.jpg"]:
print(f, os.path.getsize(f), "byte")
seed를 42로 고정해 같은 환경이면 거의 같은 크기가 나옵니다. 실제 수치는 그림 내용, Pillow 버전, 저장 옵션에 따라 달라지지만, 사진은 JPG가 작아지고 단색 그래픽은 PNG가 작아지는 방향은 구조적으로 같습니다.
한 가지 더, JPG 변환은 되돌릴 수 없습니다
JPG는 저장할 때 화질 정보를 버리는 손실 압축입니다. PNG를 JPG로 바꾸면 버려진 정보는 다시 JPG를 PNG로 되돌려도 돌아오지 않습니다. 같은 JPG를 열고 저장하기를 반복하면 화질이 조금씩 더 나빠집니다. 원본 PNG는 지우지 말고 따로 보관해 두는 편이 안전합니다.
그래서 언제 JPG로 바꿀까
결정 규칙: 색이 다채로운 사진이고 투명 배경이 없다면 JPG로 바꾸세요. 스크린샷이나 로고, 글자가 또렷한 그래픽은 PNG 그대로 두는 편이 더 작고 깨끗합니다.
사진을 웹이나 메일에 올릴 용도라면 품질 75에서 80 사이가 용량과 화질의 균형점입니다. 인쇄나 보관용 원본은 무손실인 PNG를 남겨 두고, 공유용 사본만 JPG로 만드는 방식을 권합니다.
같은 변환이라도 그림의 성격에 따라 결과가 정반대가 됩니다. 바꾸기 전에 이 그림이 사진인지 단색 그래픽인지부터 보면, 용량이 줄지 늘지 미리 짐작할 수 있습니다.
'파일 형식 백과사전' 카테고리의 다른 글
| SVG를 PNG로 변환하는 법, 출력 크기는 어떻게 정해야 할까 (0) | 2026.07.12 |
|---|---|
| 앱이 만든 .db 파일, 안에 든 데이터를 들여다보는 단계별 방법 (0) | 2026.07.11 |
| Parquet 파일 받았는데 더블클릭해도 안 열립니다, 파이썬과 비전공자용 방법까지 (0) | 2026.07.09 |
| 화질은 지키고 용량만 줄이기, 사진 한 장으로 두 방법을 실측해 봤습니다 (0) | 2026.07.08 |
| 확장자가 .jsonl인데 JSON이 깨진 게 아닙니다, JSON Lines(NDJSON) 정체와 일반 JSON과의 차이 (0) | 2026.07.07 |