무손실 압축 vs 손실 압축: 핵심 차이점 설명

압축의 본질: 같은 정보를 더 적은 데이터로 표현하기

무손실 압축과 손실 압축의 구분에 들어가기 전에, 압축이 실제로 무엇을 하는지 이해할 필요가 있습니다.

압축의 핵심은 같은 정보를 더 적은 데이터로 표현하는 것입니다. 텍스트, 이미지, 오디오, 비디오 등 모든 데이터는 "중복성"을 포함합니다. 중복성이란 정보의 의미를 잃지 않고 제거할 수 있는 부분을 가리킵니다. 압축 알고리즘의 역할은 이 중복성을 식별하고 제거하는 것입니다.

간단한 예를 들어 보겠습니다. 문자열 AAAAABBBCC는 10바이트를 차지합니다. 하지만 "각 문자와 그것이 연속으로 반복되는 횟수"를 기록하여 같은 정보를 더 간결하게 표현할 수 있으며, 5A3B2C가 됩니다 — 단 6바이트입니다. 데이터 크기는 40% 줄어들지만 의미는 동일합니다. 이것이 가장 원시적인 형태의 압축이며, Run-Length Encoding(RLE)으로 알려져 있습니다.

정보 이론의 관점에서 클로드 섀넌은 "정보 엔트로피" 개념을 도입했습니다. 데이터 스트림의 최소 평균 부호화 길이는 그 엔트로피에 의해 제한됩니다. 어떤 무손실 알고리즘도 이 이론적 한계를 깰 수 없습니다. 이는 이미 압축된 데이터를 다시 압축해도 거의 이득이 없다는 것을 의미합니다 — 중복성은 이미 제거되었기 때문입니다.

이 본질을 이해하면 근본적으로 다른 두 가지 기술적 경로가 드러납니다. 무손실 압축은 완벽한 충실도를 추구하는 반면, 손실 압축은 인간의 눈이나 귀가 쉽게 인지하지 못하는 세부 사항을 의도적으로 버리고, 그 대가로 훨씬 더 높은 압축률을 얻습니다.


무손실 압축: 모든 비트를 복원하다

무손실 압축의 핵심 약속은 복원된 데이터가 원본과 바이트 단위로 동일하다는 것입니다 — 단 한 비트도 달라서는 안 됩니다. 이 알고리즘들은 "통계적 중복성"과 "구조적 중복성"만 제거하며, 정보의 의미론적 내용은 결코 건드리지 않습니다.

DEFLATE: 가장 널리 사용되는 무손실 알고리즘

DEFLATE는 ZIP, gzip, zlib 및 많은 다른 도구의 기반이 되는 알고리즘입니다. 두 가지 고전적 기법을 우아하게 결합합니다:

  1. LZ77: 슬라이딩 윈도우를 사용하여 이미 처리된 데이터에서 반복되는 부분 문자열을 검색하고, "거리 + 길이" 포인터로 대체합니다. 예를 들어, 텍스트 파일에서 반복적으로 나타나는 "compression"이라는 단어는 첫 번째 발생 위치에 대한 역참조로 대체할 수 있습니다.
  2. 허프만 부호화: LZ77이 생성한 심볼 스트림에 가변 길이 부호화를 적용합니다. 자주 나타나는 심볼은 짧은 코드를 받고, 드문 심볼은 긴 코드를 받습니다. 이는 부호화를 엔트로피 한계에 가깝게 만듭니다.

DEFLATE의 강점은 단순성, 속도, 그리고 보편적인 호환성입니다 — 거의 모든 프로그래밍 언어의 표준 라이브러리에 구현이 포함되어 있습니다.

LZMA: 문맥 모델링을 통한 더 높은 압축률

LZMA(Lempel-Ziv-Markov chain Algorithm)는 LZ77을 기반으로 훨씬 더 큰 슬라이딩 윈도우(최대 수 GB), 더 정교한 확률 모델, 범위 부호화를 사용합니다. DEFLATE와 비교해 LZMA는 일반적으로 더 높은 압축률을 달성하지만, 압축 속도가 느리고 메모리 사용량이 많습니다. 7z 포맷은 LZMA에 기반합니다.

LZMA의 핵심 개선점은 정적 확률 테이블에 의존하지 않는다는 것입니다. 대신 문맥을 기반으로 다음 심볼의 확률을 동적으로 예측합니다. 이 "문맥 모델링"은 부호화를 이론적 엔트로피 한계에 훨씬 더 가깝게 만듭니다.

PNG 필터링: 이미지 데이터 전처리

PNG는 무손실 이미지 포맷이지만, 원시 픽셀 값에 직접 DEFLATE를 적용하지는 않습니다. 압축 전에 PNG는 각 픽셀 행에 "필터"를 적용하여 데이터가 DEFLATE에 더 유리하도록 만듭니다.

일반적인 필터는 각 픽셀과 그 왼쪽, 위쪽, 또는 왼쪽 위 이웃 픽셀 간의 차이를 저장합니다. 자연 이미지는 국소적으로 유사한 픽셀을 가지므로, 이러한 차이는 0 주변에 모이는 경향이 있습니다. 이렇게 변환된 데이터는 더 높은 중복성을 가지며, DEFLATE가 훨씬 더 효과적으로 압축할 수 있게 합니다.

이것은 ZIP이 JPEG 이미지를 효과적으로 압축할 수 없는 이유이기도 합니다. JPEG은 이미 DCT와 엔트로피 부호화를 통해 고도로 압축되어 있어, DEFLATE가 활용할 수 있는 통계적 중복성이 거의 남아 있지 않습니다. JPEG에 ZIP을 실행하면 일반적으로 크기 감소 없이 몇 바이트의 헤더 오버헤드만 추가됩니다.


손실 압축: 인지 임계값 이하에서의 교환

손실 압축의 핵심 아이디어는 인간의 인지에는 한계가 있다는 것입니다. 버려지는 세부 사항이 인지 임계값 이하에 있다면, 시각적 또는 청각적 차이는 무시할 만합니다 — 하지만 데이터 감소는 엄청날 수 있습니다.

DCT: JPEG의 수학적 기반

이산 코사인 변환(DCT)은 JPEG 이미지 압축의 심장입니다. 그 역할은 이미지를 "공간 영역"에서 "주파수 영역"으로 변환하는 것입니다.

공간 영역에서 이미지는 픽셀 밝기 값으로 표현됩니다. 주파수 영역에서 이미지는 서로 다른 주파수의 코사인 파 성분들의 합으로 분해됩니다. 저주파 성분은 크고 매끄러운 영역을 나타내고, 고주파 성분은 윤곽과 미세한 디테일을 나타냅니다.

DCT 자체는 가역적이며 정보를 잃지 않습니다. 실제 "손실"은 다음 단계인 양자화에서 일어납니다.

양자화: 손실의 원인

양자화는 고정밀 DCT 계수를 제한된 이산 값 집합에 매핑합니다. 실제로는 각 계수를 양자화 테이블의 값으로 나눈 후 정수로 반올림합니다. 인간의 눈은 고주파 디테일에 덜 민감하므로, 양자화 테이블은 고주파 계수에 더 큰 제수를 적용하여 그 중 많은 것을 0으로 만듭니다.

이 단계는 되돌릴 수 없는 정보 손실을 일으킵니다 — 한 번 0으로 반올림된 계수는 복구할 수 없습니다. 하지만 이는 동시에 엄청난 압축 기회를 만듭니다. 0의 긴 연속은 run-length encoding으로 매우 효율적으로 부호화할 수 있습니다.

양자화 테이블을 설계하는 것은 예술입니다. 제수가 클수록 압축률은 높아지지만 품질 저하가 더 눈에 띕니다. 이것이 바로 JPEG 품질 매개변수(예: quality=80)가 제어하는 것입니다 — 양자화 테이블을 늘리거나 줄입니다.

프레임 간 예측: 비디오 압축의 핵심

비디오 압축은 정지 이미지보다 한 단계 더 나아갑니다. 비디오의 연속된 프레임은 종종 거의 변하지 않으므로(예를 들어, 움직이는 인물과 정지된 배경), 모든 프레임을 전부 저장할 필요가 없습니다.

프레임 간 예측은 "움직임 추정"을 사용하여 현재 프레임과 참조 프레임 간의 변위를 찾고, "움직임 벡터"와 "잔차"만 저장합니다. 이러한 시간적 중복성의 제거 덕분에 비디오 압축률은 수백 심지어 수천 대 일에 도달할 수 있습니다 — 단일 프레임 이미지 압축이 달성할 수 있는 것을 훨씬 뛰어넘습니다.


무손실 vs 손실: 비교 다이어그램

아래의 순서도는 두 압축 계열의 핵심 분기와 전형적인 응용을 보여줍니다:

Lossless vs lossy compression technology path comparison flowchart: DEFLATE/LZMA path vs DCT/quantization path

DCT 원리 다이어그램

아래 다이어그램은 DCT가 8x8 픽셀 블록을 공간 영역에서 주파수 영역으로 변환한 후, 양자화를 통해 저주파는 보존하고 고주파는 버리는 방식을 간략히 보여줍니다:

DCT discrete cosine transform principle diagram: 8x8 pixel block conversion from spatial domain to frequency domain quantization process

코드 예제

zlib를 이용한 무손실 압축


import zlib

# 강한 반복을 포함하는 원본 텍스트 데이터
original = b"compression compression compression " * 50

# 압축
compressed = zlib.compress(original, level=9)
print(f"원본 크기: {len(original)} 바이트")
print(f"압축 후 크기: {len(compressed)} 바이트")
print(f"비율: {len(original) / len(compressed):.2f}x")

# 복원하여 데이터가 동일한지 검증
decompressed = zlib.decompress(compressed)
assert decompressed == original, "데이터 불일치!"
print("검증 통과: 복원된 데이터가 원본과 동일합니다")

이 코드를 실행하면 일반적으로 10배 이상의 압축률을 보게 되며, 복원된 데이터는 원본과 바이트 단위로 동일합니다. 이것이 "무손실"의 의미입니다.

PIL을 이용한 손실 압축


from PIL import Image
import io

# 고주파 디테일이 풍부한 테스트 이미지 생성
img = Image.new("RGB", (512, 512))
pixels = img.load()
for x in range(512):
    for y in range(512):
        # 고주파 디테일을 갖는 패턴 생성
        pixels[x, y] = ((x * 7) % 256, (y * 5) % 256, ((x + y) * 3) % 256)

# 무손실 PNG로 저장
img.save("test_lossless.png")
png_size = len(open("test_lossless.png", "rb").read())
print(f"PNG(무손실) 크기: {png_size} 바이트")

# 효과를 극대화하기 위해 품질 20의 손실 JPEG로 저장
buffer = io.BytesIO()
img.save(buffer, format="JPEG", quality=20)
jpeg_size = buffer.tell()
print(f"JPEG(손실) 크기: {jpeg_size} 바이트")
print(f"비율: {png_size / jpeg_size:.2f}x")

# JPEG를 다시 불러와 픽셀 차이 비교
buffer.seek(0)
img_jpeg = Image.open(buffer)
diff_count = sum(
    1 for x in range(512) for y in range(512)
    if img.getpixel((x, y)) != img_jpeg.getpixel((x, y))
)
print(f"변경된 픽셀: {diff_count} / {512 * 512}")
print("결론: JPEG 압축은 픽셀 값을 되돌릴 수 없게 변경합니다")

이 코드는 손실 압축의 핵심 특징을 보여줍니다. 더 작은 파일이지만, 픽셀 값이 되돌릴 수 없게 변경되었습니다.


비교 표

차원무손실 압축손실 압축
핵심 원리통계적·구조적 중복성 제거인지 임계값 이하의 정보 버림
충실도100% 가역, 복원 후 동일비가역, 회복 불가능한 손실
대표 알고리즘DEFLATE, LZMA, Brotli, ZstandardDCT+양자화, 웨이블릿, MDCT
주요 기법LZ77, 허프만 부호화, 범위 부호화변환 부호화, 양자화, 예측
전형적 응용ZIP, GZIP, 7Z, PNG, FLACJPEG, WebP, H.264, MP3, AAC
가장 적합한 용도텍스트, 소스 코드, 아카이브, 의료 영상사진, 비디오, 음악, 스트리밍
전형적 압축률보통 2배~5배보통 10배~100배 이상
부적합 용도이미 압축된 데이터(예: JPEG 파일)정확한 재현이 필요한 데이터(예: 법률 문서)

FAQ

Q1: ZIP은 왜 JPEG 이미지를 압축할 수 없나요?

JPEG이 생성되는 시점에 이미 DCT, 양자화, 엔트로피 부호화를 거쳤습니다. 데이터의 통계적 중복성은 거의 완전히 제거되었습니다. DEFLATE는 활용 가능한 반복 패턴을 찾을 수 없으므로, JPEG에 ZIP을 실행해도 크기가 줄어들지 않을 뿐 아니라 오히려 몇 바이트의 헤더 오버헤드가 추가될 수 있습니다.

Q2: 같은 이미지에서 PNG가 항상 JPEG보다 큰가요?

반드시 그렇지는 않습니다. 단색의 큰 영역이나 제한된 팔레트를 가진 이미지(로고, 아이콘, 스크린샷 등)에서는 PNG의 필터+DEFLATE 조합이 JPEG보다 작은 경우가 많고 완벽한 품질을 보존합니다. 하지만 색이 풍부한 자연 사진에서는 JPEG의 DCT+양자화 조합이 일반적으로 10배 이상의 압축률을 달성하여 PNG보다 훨씬 작아집니다.

Q3: 같은 파일을 무손실 알고리즘으로 반복적으로 압축할 수 있나요?

불가능합니다. 무손실 압축의 각 패스는 데이터를 엔트로피 한계에 가깝게 만듭니다. 첫 번째 패스 이후 중복성은 대부분 사라지고, 두 번째 패스는 더 이상 활용할 것이 거의 없습니다 — 추가되는 메타데이터 때문에 오히려 약간 커질 수도 있습니다. 그래서 "이미 압축된 파일을 압축하는 것"은 무의미합니다.


요약

무손실 압축과 손실 압축은 대립하는 진영이 아니라, 서로 다른 정보 특성에 대해 내린 최적의 선택입니다:

  • 무손실 압축은 "단 한 비트도 틀려서는 안 되는" 데이터 — 텍스트, 코드, 아카이브 — 에 사용됩니다. LZ77과 허프만 부호화 같은 기법을 사용하여 통계적 중복성을 제거하면서 완벽한 재구성을 보장합니다.
  • 손실 압축은 "눈과 귀가 인지하지 못하는" 세부 사항 — 사진, 비디오, 음악 — 에 사용됩니다. DCT, 양자화, 프레임 간 예측을 사용하여 인지 임계값 이하에서 절충안을 만들고, 제어된 정보 손실을 압축률의 자릿수 개선과 맞바꿉니다.

이 두 경로의 근본적인 차이를 이해하는 것은 모든 압축 기술을 마스터하는 초석입니다. 후속 글에서는 각 경로를 따라 구체적인 알고리즘 구현을 파고들며, 압축의 우아함을 한 줄씩 이해해 나갈 것입니다.

관련 글:

파일 압축이 필요하신가요? SmartSlim을 사용해 보세요

자체 개발한 Rust 압축 엔진 기반으로 PDF/이미지/비디오/Office/OFD 등 10대 분류 40+ 포맷을 지원합니다. 로컬 압축으로 데이터가 외부로 나가지 않습니다.