구축 방법 — Image Compression · v1.0 · 2026-10-27
■ 방법
- 탭 5개: Color Spaces / DCT Blocks / Quantization / Entropy Coding / When JPEG Fails. 탭마다 체험 3~4개와 개요·요약·참고문헌. 그림·품질·색 줄이기 설정은 모든 탭이 함께 씀(?p=로 이어받음)
- 새 체험: 채널별 보기와 픽셀 값 읽기, Y만·색만 해상도 줄이기 비교, DCT 무늬 64개 고르기, 앞 k개 계수로 블록 되살리기, 8×8 블록 직접 칠하기, 블록 하나의 양자화 전후·오차, 고른 표와 표준 표 비교(파일 크기를 이분 탐색으로 맞춤), 블록 하나의 허프만 부호 손풀이, 바이트 쓰임새, 기호 엔트로피 대비 표준 허프만 평균, 오차 지도와 8×8 격자, 다시 저장(같은 격자·1픽셀 밀기), 세 그림의 크기–PSNR 곡선
- 엔진 jpeg-core.js는 옛 jpeg/에서 그대로 가져오고, 표를 직접 줄 수 있는 선택(opts.qy·qc)과 허프만 표 내보내기만 더함(기본 경로는 바뀌지 않음)
- 규칙 계산: 기본(baseline) JPEG 인코더를 브라우저용 JavaScript로 직접 구현. ITU-T T.81 부록 K 표준 양자화 표·허프만 표
- 단계: RGB → YCbCr(JFIF) · 4:2:0 또는 4:4:4 · 8×8 DCT · IJG 품질 공식으로 양자화 표 조절 · 지그재그 · 런 길이 · 허프만 · JFIF 마커
- 만든 바이트를 브라우저 자체 디코더로 열어 화면에 보이고 PSNR을 잼
- 학습 없음 · 실행 20261025T024605Z · Node 22.23, Pillow 12.3.0(libjpeg)
- LLM 없음
■ 데이터
- 커피 잔 600×400 · scikit-image 0.26 data.coffee · CC0(사진 Rachel Michetti)
- 고양이 451×300 · scikit-image 0.26 data.chelsea · CC0(사진 Stefan van der Walt)
- 글자와 선 480×320 · 코드로 그림(Pillow)
- 성격: 공개 데이터 + 합성. 사용자가 연 사진은 긴 변 800픽셀로 줄여 브라우저 안에서만 처리, 업로드·저장 없음
■ 검증
- 그림 3장 × 품질 10·30·50·75·90 × 4:2:0·4:4:4 = 30개 파일을 libjpeg(Pillow)로 열어 대조. 모두 정상으로 열림
- 크기: libjpeg가 같은 표·같은 설정(최적화 끔)으로 만든 파일과 차이 −1.1%~+0.6%
- PSNR(libjpeg로 연 결과): 커피 잔 품질 50·4:2:0 30.50 dB(libjpeg 자체 인코딩 30.50 dB)
- 커피 잔 품질 50·4:2:0: 이 페이지 27,414 B / libjpeg 27,355 B / PNG 441,801 B / 날것 720,000 B
- 글자와 선: PNG 25,970 B가 품질 90 JPEG(4:2:0 27,000 B, 4:4:4 37,326 B)보다 작음
- 헤드리스 Chromium: 기본 화면 파일 27,414 B, 브라우저 디코딩 PSNR 30.50 dB(Node 결과와 같음)
- 2026-10-26 vision/로 옮긴 뒤 tests/image-compression/verify.py 다시 실행: 30개 파일 크기·PSNR 모두 옛 측정과 같음(커피 잔 품질 50 4:2:0 27,414 B, 30.50 dB)
■ 범위
- 8비트 RGB 그림, 긴 변 800픽셀 이하, 품질 1~100, 4:2:0·4:4:4. 점진(progressive)·산술 부호화·최적 허프만은 없음
■ 출처
- ITU-T Recommendation T.81 (1992) | ISO/IEC 10918-1. Digital compression and coding of continuous-tone still images.
- Wallace (1991). The JPEG still picture compression standard. Communications of the ACM.
- Independent JPEG Group, libjpeg 품질 공식(jcparam.c).
- Ballé et al. (2018). Variational image compression with a scale hyperprior. ICLR.
- 데이터: scikit-image 0.26 예시 그림 · CC0 · https://scikit-image.org
How it's built — Image Compression · v1.0 · 2026-10-27
■ Method
- 5 tabs: Color Spaces / DCT Blocks / Quantization / Entropy Coding / When JPEG Fails. Each tab has 3–4 hands-on parts plus overview, summary and references. Image, quality and subsampling settings are shared by all tabs (carried in ?p=)
- New hands-on parts: per-channel view with pixel read-out, reducing Y only vs colour only, picking among the 64 DCT patterns, rebuilding a block from its first k coefficients, painting your own 8×8 block, one block before and after quantization with its error, flat vs standard table at matched file size (bisection), hand-encoding one block with Huffman codes, where the bytes go, symbol entropy vs standard Huffman average, error map with the 8×8 grid, re-saving (same grid vs 1-pixel shifts), size–PSNR curves for three images
- The engine jpeg-core.js comes unchanged from the former jpeg/ page, plus an option to pass tables directly (opts.qy, qc) and an export of the Huffman tables; the default path is unchanged
- Rule-based computation: a baseline JPEG encoder written from scratch in browser JavaScript. Standard quantization and Huffman tables from ITU-T T.81 Annex K
- Steps: RGB → YCbCr (JFIF) · 4:2:0 or 4:4:4 · 8×8 DCT · quantization table scaled by the IJG quality formula · zigzag · run-length · Huffman · JFIF markers
- The bytes are opened by the browser's own decoder for display and PSNR
- No training · run 20261025T024605Z · Node 22.23, Pillow 12.3.0 (libjpeg)
- No LLM
■ Data
- Coffee cup 600×400 · scikit-image 0.26 data.coffee · CC0 (photo by Rachel Michetti)
- Cat 451×300 · scikit-image 0.26 data.chelsea · CC0 (photo by Stefan van der Walt)
- Text and lines 480×320 · drawn by code (Pillow)
- Nature: public data + synthetic. Visitors' photos are shrunk to 800 px on the long side and processed in the browser only, never uploaded or saved
■ Validation
- 3 pictures × quality 10, 30, 50, 75, 90 × 4:2:0 and 4:4:4 = 30 files, opened with libjpeg (Pillow). All decode correctly
- Size: −1.1% to +0.6% versus libjpeg with the same tables and settings (optimization off)
- PSNR (decoded by libjpeg): coffee cup, quality 50, 4:2:0: 30.50 dB (libjpeg's own encoding 30.50 dB)
- Coffee cup, quality 50, 4:2:0: this page 27,414 B / libjpeg 27,355 B / PNG 441,801 B / raw 720,000 B
- Text and lines: PNG at 25,970 B is smaller than a quality-90 JPEG (4:2:0 27,000 B, 4:4:4 37,326 B)
- Headless Chromium: default file 27,414 B, browser-decoded PSNR 30.50 dB (same as Node)
- Re-run after the move to vision/ (2026-10-26), tests/image-compression/verify.py: all 30 file sizes and PSNRs identical to the earlier measurements (coffee cup q50 4:2:0 27,414 B, 30.50 dB)
■ Scope
- 8-bit RGB pictures up to 800 px on the long side, quality 1–100, 4:2:0 and 4:4:4. No progressive mode, arithmetic coding or optimized Huffman tables
■ Sources
- ITU-T Recommendation T.81 (1992) | ISO/IEC 10918-1. Digital compression and coding of continuous-tone still images.
- Wallace (1991). The JPEG still picture compression standard. Communications of the ACM.
- Independent JPEG Group, libjpeg quality formula (jcparam.c).
- Ballé et al. (2018). Variational image compression with a scale hyperprior. ICLR.
- Data: scikit-image 0.26 sample images · CC0 · https://scikit-image.org
■ History
- 2026-10-27 · v1.0 · Released