Skip to content

dknos/anime-barcodes

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

44 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Anime Barcodes

Every frame of an anime, compressed into a single image — then analysed back into prose, palettes, and perceptual neighbours.

→ Browse the site

267 anime · 1996–2025 · 6 barcode variants each · k-means palettes, OKLab perceptual neighbours, brightness arcs, hue distributions. Long-form decade essays, hand-feeling per-show commentary, and a dedicated frame-by-frame deep-dive on Serial Experiments Lain.


Featured: the Lain deep-dive

The site's flagship is a single-show portfolio piece on Serial Experiments Lain (1998) — built ground-up in the show's own visual register (cathode-blue + warm-tan accents on a black void, scanline overlays, JetBrains Mono + Cormorant Garamond).

What's there:

  • Walk the Season — interactive 13-Layer hover strip. Mouse over any Layer's slice barcode and a sticky panel updates with the closest of 24 extracted keyframes, the timestamp, the current act, the act-brightness, an act-palette, a hand-written plot beat, and the cast on screen.
  • Frame Atlas, measured — 312 keyframes (24 × 13 Layers) extracted from the source video. Each one carries its measured brightness, saturation, and dominant hue. Sortable by Layer, brightness ascending/descending, saturation, hue (ROYGBIV). Extremes panel calls out the literal darkest, brightest, most-saturated, and most-desaturated frames in the run — found by the algorithm, not by me.
  • Hue spectrogram — 13 Layers × 12 hue buckets stacked-bar.
  • Per-Layer breakdown — palette, act-thirds bars, slice barcode, 24-frame keyframe strip per Layer, with a one-paragraph reading anchored to a measurable data point.
  • Authorial-intent research — primary citations from cjas.org Otakon-2000 / AX-2001 / Anime Colony chat / ANN-2005, fact-checked against lain.wiki. Voice cast + Triangle Staff postscript. Honest non-attribution of the J.J. Burnel / Bôa fan claim.
  • Cultural afterlife — the Milady/Remilia link's primary-source fragility, SystemSpace as the cleanest crypto-art continuity, Texhnolyze as the strongest creator-continuity chain, Lain's afterlife in draincore + schizoposting + cyberpunk-revival.

Every Layer beat was fact-checked against lain.wiki before shipping. The page is the part of the site that exists to be read, not browsed.


What is this?

A barcode takes every sampled frame of an anime and compresses it into a single vertical strip. Stack them left-to-right and you get a visual fingerprint of the entire show — its colour mood, pacing, and aesthetic in one image.

Each entry gets 6 variants rendered from the actual video:

Variant What it shows
Pixel Slice 1px center crop of each frame — raw, saturated, exact scene colour
Smooth Average Mean colour of every pixel in each frame — the emotional tone
Rank Mosaic Columns sorted by luminance — dark left, bright right — full palette as a gradient
Radial / Circle Polar transform of the average barcode — the show as a clock face
Edit Pace Frame-to-frame colour delta — bright columns = fast cuts, dark = slow scenes
Colour Temperature Red-Blue channel ratio per frame — warm gold vs cool teal

Features

Color Twins (OKLab perceptual neighbours)

Every show gets a Color Twins panel listing its closest five palette neighbours from across the archive — computed in OKLab perceptual space (chromatic-weighted distance between palette colours, with greys / blacks / whites filtered out as universal). Land of the Lustrous finds Aria the Animation. Lain finds My Hero Academia (cool-palette match, surprising). The metric is symmetric mean-of-min OKLab distance, cached to a JSON index for instant lookup.

Decade essays

Four long-form essays (~1620–1900 words each), one per decade: 1990s — 2020s. Hand-written, anchored to specific show data. The 1997 rupture, FMA 2003 vs FMA Brotherhood 2009, KyoAni's painterly 2010s, MAPPA's industrial-grey 2020s.

Per-show commentary

40 shows have hand-curated editorial commentary; the remaining 227 have AI-generated paragraphs (DeepSeek-Reasoner / DeepSeek-Chat) anchored to the specific palette, brightness arc, and hue distribution of each show, with curated style anchors. Zero shows fall back to template-generated text — every detail page reads.

Insights, studios, trends pages

Cross-archive analytics: brightness vs. saturation scatter, edit-pace vs. MAL score, studio fingerprints (KyoAni vs MAPPA vs Trigger averaged palettes), warmth-over-time, hue distribution evolution from 1996 → 2025.

Year picker + mobile nav

Top-bar YEAR ▾ select routes straight to any year's page. Hamburger drawer at <760px keeps the nav in a single row regardless of viewport. Image lightbox on every barcode + keyframe — click any image, fullscreen overlay with × / Esc / click-outside dismiss.


Gallery

Serial Experiments Lain (1998)

Warm-grays, cool-grays, one tan, one navy, zero primary colours

avg slice

Land of the Lustrous (2017)

Gem-coloured CG — one of the most distinctive palettes in any anime

slice avg

Cowboy Bebop (1998)

Jazz-era warmth — amber, rust, and space-black across the full run

slice avg

Demon Slayer (2019)

High contrast — flame-lit fights against dark backgrounds, ufotable's industrial sublime

slice avg

Puella Magi Madoka Magica (2011)

Pastel-to-black — the colour shift as the show turns dark is visible in the barcode

slice avg

Chainsaw Man (2022)

Deep reds, flesh tones, sudden bursts of white — MAPPA's kinetic colour language

slice avg


How it works

Pipeline

Jikan MAL API          Stream resolver            ffmpeg
──────────────    →    ──────────────────────  →  ──────────────────────────
Top anime by year      Resolve cached stream       Sample 1 frame / 7.5s
score + members        URL for episode or movie    Crop / average → tile
                       Download to local tmp       6 variants rendered
                                                   ↓
PIL + numpy + OKLab    GitHub Pages                analyze.py
──────────────    →    ──────────────────────  ←   ──────────────────────────
K-means palette        Static site generated       K-means palette (8 colours)
Brightness arc         Committed + pushed          Hue distribution (12 bins)
Color temperature      ~340 MB total               Brightness arc (3-act)
Edit pace delta                                    Saturation average
OKLab perceptual                                   Per-act palette
neighbour index

Stages

  1. expand_lists.py — Hits the Jikan v4 API to pull top-rated anime per year (by MAL score + member count); merges into lists/YEAR.json.
  2. pipeline.py — For each entry: resolves a stream URL, downloads, renders 6 barcode variants with ffmpeg, analyses with numpy/PIL, writes stats.json + meta.json.
  3. derive_analysis.py — Post-processes barcode_avg.png to generate Edit Pace and Colour Temperature barcodes without re-downloading.
  4. scripts/generate_commentaries.py — DeepSeek-Reasoner / DeepSeek-Chat generates editorial paragraphs anchored to palette + brightness + hue-distribution, using curated shows as style anchors.
  5. scripts/extract_lain_frames.py — Re-resolves Lain episodes, extracts 24 keyframes per Layer at 480w (skipping OP/ED), deletes the .mkv. With per-episode timeout protection.
  6. lain_feature.py — Standalone module that reads existing analysis + extracted frames + research files and emits the dedicated /lain/ deep-dive page with computed per-frame stats cached to .lain_frame_stats.json.
  7. generate_site.py — Reads all barcodes/*/ dirs, builds the full static site into site/, copies barcode PNGs, writes HTML/CSS, generates the OKLab palette-neighbour index.

Analysis

Each anime gets a stats.json with:

  • K-means palette — 8 dominant colours from column means (the temporal colour data, not raw pixels)
  • Per-act palette — opening / middle / closing third k-means dominants
  • Brightness arc — Mean luminance per column split into thirds, classified as rising / falling / arc-up / dark-midpoint / flat
  • Hue distribution — 12-bin HSV histogram of column mean colours
  • Mean complexity — frame-to-frame colour delta as a proxy for edit pace

Per-show OKLab palette neighbours are precomputed in generate_site.py:build_similarity_index — symmetric mean-of-min OKLab distance with chromatic-weighted matching (greys/blacks/whites filtered out). Cached to .similarity_cache.json so subsequent rebuilds are free.


Running it yourself

Requirements

pip install pillow numpy
# ffmpeg must be on PATH
# Stream provider account + API token required for the download stage
# (the site / analysis / Lain feature don't need streaming once the .mkvs are
#  processed — only the initial pipeline.py + extract_lain_frames.py do)

Quickstart

git clone https://github.com/dknos/anime-barcodes.git
cd anime-barcodes-claudec

# Set your stream provider token
export STREAM_API_TOKEN=...

# Pull top-N anime per year
python3 expand_lists.py

# Process one year (or all)
python3 pipeline.py --year 2019
python3 pipeline.py --all

# Derive secondary barcodes (no video needed)
python3 derive_analysis.py

# Generate the AI commentary pass (DeepSeek)
export DEEPSEEK_API_KEY=...
python3 scripts/generate_commentaries.py --workers 6 --model deepseek-chat

# Extract Lain keyframes (only needed once)
python3 scripts/extract_lain_frames.py

# Build the site
python3 generate_site.py

NVDEC hardware decode (NVIDIA GPUs)

python3 pipeline.py --year 2019 --gpu 0

Tech stack

Layer Tool
Anime metadata Jikan v4 (MyAnimeList API wrapper)
Stream resolution Cached stream provider
Video processing ffmpeg (fps, crop, scale, tile, slice)
Image processing Pillow + numpy
Colour analysis K-means clustering, HSV histograms, OKLab perceptual distance
Editorial prose DeepSeek-Reasoner / DeepSeek-Chat (OpenAI-compatible API)
Charts Chart.js v4
Fonts Inter, Cormorant Garamond, JetBrains Mono, Fraunces
Hosting GitHub Pages

Data summary

  • 267 anime processed
  • 1996–2025 continuous coverage
  • ~7.5 second frame sampling interval
  • 6 barcode variants per anime · 1920 × 1080 PNG
  • 312 extracted keyframes for Lain (24 × 13 Layers, 480w JPEG)
  • OKLab palette index precomputed across all 267 entries
  • 40 hand-curated + 237 AI-generated show commentaries
  • 4 decade essays (~7,200 words total)
  • ~340 MB total site weight

Contributing

Add an anime

Edit lists/YEAR.json:

{
  "mal_id": 1535,
  "title": "Death Note",
  "title_english": "Death Note",
  "score": 8.62,
  "episodes": 37,
  "imdb_id": "tt0877057",
  "media_type": "TV"
}

Then python3 pipeline.py --year 2006.

Improve the analysis

Targets:

  • Per-frame measurement scaled across the whole archive (currently Lain-only)
  • Studio-fingerprint clustering (does Trigger have a measurable signature?)
  • Scene-type detection (action / dialogue / establishing)
  • Cross-year comparisons (is anime getting darker over time?)

Fix a bad barcode

Sometimes stream resolution picks a low-quality source:

rm -rf barcodes/YEAR/SLUG/
python3 pipeline.py --year YEAR --force

Built with Python, ffmpeg, OKLab, and the conviction that the colour data is already the analysis.

About

267 anime as barcodes (1996-2025): k-means palettes, OKLab perceptual neighbours, brightness arcs, decade essays, and a frame-by-frame deep-dive on Serial Experiments Lain

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors