PNG 란?
PNG(Portable Network Graphics)는 웹 그래픽이나 로고, 아이콘 등과 같이 투명한 배경이나 반투명 효과가 필요한 이미지에 주로 사용되는, 무손실 압축을 지원하며 이미지 품질 저하 없이 파일을 저장할 수 있는 이미지 파일 형식 중 하나이다.
특징
| 항목 | 설명 |
| 압축 방식 | 무손실 압축 (zlib/DEFLATE) |
| 색상 지원 | Grayscale, Truecolor(RGB), Indexed color, 알파 채널(투명도) |
| 투명도 지원 | 알파 채널 또는 색상 키(transparent color) |
| 특허 문제 | 없음 (자유롭게 사용 가능) |
| 애니메이션 지원 | 기본 PNG는 지원하지 않으며, APNG 확장 사용 시 가능 |
| 용도 | 아이콘, 로고, 텍스트 이미지, 투명 배경 이미지 등 |
PNG 파일 구조

PNG 파일은 8바이트 시그니처와 chunk들의 연속으로 구성된다.
PNG는 아래와 같은 블록 기반 구조를 가진다.
[ PNG Signature (8 bytes) ]
[ IHDR Chunk ]
[ IDAT Chunk(s) ]
[ IEND Chunk ]
그리고 각 블록은 'chunk(청크)' 라는 단위로 구성되어 있다.
PNG Signature
PNG 파일의 가장 첫 8 바이트
모든 PNG 파일은 고정된 시그니처로 시작되며, 파일 형식을 식별하는 데 사용된다.
137, 80, 78, 71, 13, 10, 26, 10 (10진수 표현)
89 50 4E 47 0D 0A 1A 0A (16진수 표현)
청크(Chunk)의 구조
Length (4 bytes) // Data 필드의 길이
Type (4 bytes) // 청크 이름(ASCII)
Data (n bytes) // 실제 데이터
CRC (4 bytes) // Type + Data에 대한 CRC-32 체크섬
주요 청크(Chunk) 설명
| 청크 | 필수 여부 | 설명 |
| IHDR | O | 이미지의 기본 정보 (폭, 높이, 색상 등) |
| PLTE | X | 팔레트 정보 (Indexed color에서 사용) |
| IDAT | O | 이미지의 압축된 픽셀 데이터 (여러 개 가능) |
| IEND | O | 파일의 끝을 나타냄 |
| tEXt/zTXt/iTXt | X | 텍스트 정보 (주석) |
| gAMA/sRGB | X | 감마 및 색공간 정보 |
IHDR 청크 상세 구조
IHDR은 PNG에서 가장 먼저 등장하는 청크로, 이미지에 대한 메타 정보를 담는다.
Data의 길이는 항상 13바이트이며, 다음과 같은 필드로 구성된다.
| 필드 | 크기 | 설명 |
| Width | 4 bytes | 이미지 너비 (픽셀 단위) |
| Height | 4 bytes | 이미지 높이 |
| Bit depth | 1 bytes | 픽셀당 비트 수 (1, 2, 4, 8, 16 중 하나) |
| **Color type | 1 bytes | 색상 형식 (0=그레이스케일, 2=RGB, 3=Indexed, 4=Gray+Alpha, 6=RGBA) |
| Compression | 1 bytes | 압축 방법 (항상 0 - zlib/DEFLATE) |
| Filter | 1 bytes | 필터 방법 (항상 0) |
| Interlace | 1 bytes | 인터레이스 방식 (0=없음, 1=Adam7 사용) |
이미지 데이터와 IDAT 청크
이미지의 실질적인 픽셀 정보는 IDAT 청크에 저장된다.
- IDAT는 Image DATa 라는 의미
- 실제 이미지의 픽셀 정보가 저장되는 곳
- 한 개 이상 존재할 수 있고, 연결되어 하나의 스트림처럼 해석된다.
이미지 데이터는 스캔라인 단위로 구성된다.
- PNG는 위에서 아래로 한 줄씩 처리하고, 각 줄을 스캔라인(scanline)이라고 부른다.
- 각 스캔 라인 구성은 [필터 바이트 (1 byte)] + [픽셀 데이터들] 이런 형태
- 예시 : 한 줄이 99999 라면?
- 필터 바이트 : 0 (기본 필터)
- 픽셀 데이터 : [255, 255, 255, 255, 255] (9 → (9/9)*255 = 255)
- 최종 라인 데이터 : [0, 255, 255, 255, 255, 255]
- 예시 : 한 줄이 99999 라면?
필터(Filter): 압축 효율을 높이기 위한 PNG 전처리 기술
- PNG는 각 줄마다 필터 타입을 선택할 수 있다. (0 ~ 4)
- 목적: 인접 픽셀/줄과의 차이를 이용해 데이터 중복도를 높임 -> 압축 효율 향상
- 가장 일반적인 필터 : 0 (None) -> 원본 그대로 저장
필터가 적용된 모든 스캔라인은 **zlib/deflate로 압축됨
- PNG는 IDAT에 픽셀 데이터를 압축된 상태로 저장
- 압축 방식 : zlib 포맷 + 내부 deflate 알고리즘
- 모든 스캔라인을 하나로 합쳐 zlib로 압축하고 IDAT 청크에 삽입!
IEND 청크
PNG 파일의 종료를 나타내는 청크. 데이터가 없으며 항상 길이가 0이다.
PNG 생성 과정
- PNG Signature 작성
- IHDR 청크 작성
- 픽셀 데이터를 스캔라인 단위로 구성 (각 줄 시작에 **필터 바이트(0), 그 뒤에 픽셀 값 배열)
- 전체 스캔 라인을 zlib 방식으로 압축
- IDAT 청크 작성
- IEND 청크 작성
- 각 청크에 CRC-32 체크섬 계산
- 최종 PNG 파일 조립
CRC32
오류 검증용 체크섬
- 각 chunk 뒤에는 CRC32라고 하는 숫자가 붙는데, chunk가 깨지거나 손상됐는지 확인하는 용도이다.
- 이걸 넣지 않으면 PNG 뷰어가 잘못된 PNG라고 거부하게 된다.
PNG의 Color Type
| color type | 값 | 색 구성 | 알파 지원 | 설명 |
| 0 | Grayscale | 1 채널 (회색조) | 없음 | 흑백 또는 회색 이미지 (예: 흑백 사진) |
| 2 | Truecolor (RGB) | 3 채널 (R, G, B) | 없음 | 일반적인 컬러 이미지 |
| 3 | Indexed Color | 1 바이트 (팔레트 인덱스) | 없음 | 팔레트를 참조하는 방식 (256색 이하) |
| 4 | Grayscale + Alpha | 2 채널 (Gray, Alpha) | 있음 | 투명도 포함된 회색조 |
| 6 | Truecolor + Alpha | 4 채널 (R, G, B, A) | 있음 | 투명도를 포함한 일반 컬러 이미지 (PNG에서 가장 일반적) |
- Grayscale
- 픽셀당 1바이트 (8-but gray)
- 0 = 검정, 255 = 흰색
- Truecolor
- 픽셀당 3바이트 (R, G, B)
- [255, 0, 0] = 빨간색
- RGBA
- 픽셀당 4바이트 (R, G, B, A)
- [0, 255, 0, 128] = 반투명 초록
zlib deflate 압축
zlib deflate 는 PNG 이미지 데이터 (IDAT 청크)에 사용되는 압축 알고리즘이다.
무손실 압축 방식으로, 이미지 품질 손상없이 용량을 줄일 수 있다.
PNG 파일은 내부 이미지 데이터를 zlib 포맷으로 압축해서 저장하고, 브라우저나 뷰어가 이를 해제해서 보여준다.
zlib는 압축 데이터 포맷을 정의한 컨테이너 포맷이며, 그 안에서 실제 압축 알고리즘으로는 DEFLATE를 사용한다.
// 구조
[zlib 헤더] + [deflate로 압축된 데이터] + [ADLER32 체크섬]
PNG에서 zlib deflate 압축을 쓰는 이유
- 무손실 : 이미지 품질을 완전히 유지함
- 효율적 : 텍스트, 이미지 등에서 중복 패턴을 잘 찾아냄
- 라이센스 없음 : 자유롭게 사용 가능
- 빠름 : 압축/해제 속도가 비교적 빠름
- 표준화된 압축
DEFLATE ?
DEFLATE는 다음 두가지 알고리즘을 조합한 무손실 압축 알고리즘이다.
- LZ77 : 반복되는 문자열을 참조(백 포인터)로 바꿈
- 허프만 코딩 : 자주 등장하는 바이트를 짧은 비트로, 드문 바이트는 긴 비트로 인코딩
Filter Byte
PNG는 무손실 압축 포맷이므로 zlib(Deflate)알고리즘으로 압축을 하는데, 이미지 원시 데이터는 일반적으로 중복이 적고 변화가 많아 압축 효율이 낮을 수 있다.
PNG는 필터링 -> 압축 구조를 취함으로써, 각 스캔라인의 데이터를 다음과 같이 전처리한다.
- 이웃 픽셀(좌/상)의 값을 참고하여 변화량(차이값)을 기록
- 변화량은 원본보다 중복이 많고 압축에 유리
즉, 필터 바이트는 이 줄은 어떤 필터를 썼다. 라는 것을 알리기 위한 용도로 압축 전 원시 데이터의 맨앞에 필터바이트 1개가 반드시 포함되어야 한다. 그 중 가장 간단한 필터는 0(None)으로, 원시 데이터를 그대로 사용하게 된다.
'cs' 카테고리의 다른 글
| 배열(Arrary)이란? (0) | 2025.10.05 |
|---|---|
| Hash 란? (0) | 2025.10.02 |
| [cs] 2. 네트워크 (기초) (0) | 2025.07.12 |
| Proxy (Reverse Proxy / Forward Proxy) (0) | 2025.06.23 |
| 라이프 사이클 (LifeCycle)에 대한 이해 (0) | 2025.06.23 |