Every colour on your screen is a number.
Paleta takes one photo of a jeepney apart, pixel by pixel, until you can see the numbers.
A pixel is three lights
Your screen has no yellow in it. Each pixel is three tiny lights, red, green and blue, and each one’s brightness is a number from 0 to 255. Mix 242 red, 194 green and 48 blue and your eye sees jeepney yellow.
Two lights at full strength make a secondary colour: red and green make yellow, green and blue make cyan, blue and red make magenta. All three at 255 make white; all three at 0, black. Try each one.
Same colour, five names
RGB, HEX, HSL, HSV and CMYK are five ways of writing down one colour. HEX is RGB in base 16. HSL says it the way people talk: which hue, how vivid, how light. HSV (also called HSB) keeps the hue but swaps lightness for value: 100% value is the pure colour, not white. CMYK is subtractive, ink on paper, so it can only approximate a colour made of light.
Drag the handle on the wheel, or type into any row.
Colours that go together
Colour theory lays the hues out on a wheel. A colour scheme is a rule for picking hues by where they sit on it: complementary colours face each other, analogous colours sit side by side, triadic colours are spread evenly in thirds. Designers use these rules so colours look chosen, not random.
Pick a scheme, then turn the base hue. It starts at jeepney yellow, 45°.
Bits decide how many colours
Every bit you add doubles the values a pixel can hold: n bits give 2n. One bit is two values, black or yellow. Four bits give sixteen steps, and you can see every one. Twenty-four bits, eight per channel, give over sixteen million colours, more than the eye can separate.
colours = 2n
Read the histogram
A histogram counts how many pixels sit at each brightness level, from black on the left to white on the right. It is the quickest way to judge a photo’s exposure: a well-exposed shot spreads across the whole range, a badly exposed one piles up at one end.
Switch the exposure and watch where the pixels go.
Squeeze the jeepney
Quantization keeps a small palette and repaints every pixel with its nearest match. Drag the divider across the jeepney: the left side is the original, the right is what survives. Fewer colours means fewer symbols to encode, so the file compresses better.
Uniform cuts every channel into equal steps. Median cut splits the photo’s own colours into boxes of equal population, so it spends colours where the photo needs them.
24 shades in the photo
snap to a 4-colour palette, and redraw the gradient as
Without dithering: four flat bands
With Floyd-Steinberg dithering: the same four colours, scattered
Uniform vs median cut
Uniform cuts every channel into equal steps. Median cut splits the photo’s own colours into boxes of equal population.
JPG, PNG or WebP, chosen or dropped on the image. It never leaves your browser.
Photo: Kevin Lawrenze Lapuz, Ho Chi Minh City. At 8 colours the sky breaks into bands and the city loses nearly all of its colour.
Method
Dithering
Palette (LUT): 16 entries
16 colours used, 4 bits per pixel, est. size …
Estimated size is the raw indexed pixels plus the palette, before any compression.

A real file: jeepney-256.png
The slider above is a live preview. This is the jeepney actually saved with a 256-colour palette (median cut, no dithering): every pixel is one 8-bit index into that palette. Saved as a 24-bit PNG the same 750 × 500 image weighs 683 KB; indexed, it is 227 KB, a third of the size, and the eye barely notices.
Hear quantization
Sound is quantized too. Each sample of a wave is a number, and bit depth decides how many values it can take. Cut the bits and the smooth wave becomes a staircase you can hear as fizz and grit. Link the slider to the jeepney and one number drives both.
The tone never plays on its own; press Play.
Check yourself
Five questions, one for each big idea. A wrong answer doesn’t just say so: it sends you back to the section that explains it.
Nothing is recorded or graded.
Technical Media Spec
Every media file on this page: what it weighed before and after, how many colours or bits it keeps, and how it was squeezed.
Scroll sideways →
| Asset Name & File Format | Original Size → Compressed | Color Depth / Quantization | Compression Algorithm |
|---|---|---|---|
| jeepney-hero.webp WebP · hero and quantizer |
4.3 MB raw bitmap (1500 × 1000 × 3 bytes) → 190 KB WebP (q80) |
24-bit RGB, 8 bits per channel | WebP lossy: block prediction and transform coding, then entropy coding |
| saigon-sky.webp WebP · 3:2 crop, banding sample in 06 |
1.8 MB JPEG original (1932 × 2576) 4.3 MB raw bitmap (1500 × 1000 × 3) → 189 KB WebP (q80) |
24-bit RGB, 8 bits per channel | WebP lossy: block prediction and transform coding, then entropy coding |
| subpixels-300x.webp WebP · 2:1 crop, subpixel photo in 01 |
131 KB JPEG original (1280 × 1024) 2.3 MB raw bitmap (1280 × 640 × 3) → 28 KB WebP (q90) |
24-bit RGB, 8 bits per channel | WebP lossy: block prediction and transform coding, then entropy coding |
| cmyk-halftone.webp WebP · 1:1 centre crop, halftone photo in 02 |
2.0 MB JPEG original (1600 × 1200) 1.1 MB raw bitmap (720 × 540 × 3) → 140 KB WebP (q80) |
24-bit RGB, 8 bits per channel | WebP lossy: block prediction and transform coding, then entropy coding |
| jeepney-256.png PNG-8 · quantized sample |
683 KB as 24-bit PNG → 227 KB as 8-bit indexed PNG |
8-bit indexed: 256-colour palette (median cut) | PNG: DEFLATE (LZ77 + Huffman coding), lossless |
| crusher-demo.mp3 MP3 · #hear demo |
886 KB WAV (16-bit PCM, 44.1 kHz) → 121 KB MP3 (96 kbps) |
16-bit PCM source, mono; the demo itself steps down from 16 to 1 bit | MP3: perceptual MDCT coding + Huffman coding, lossy |
| colour-wheel.svg SVG · #models wheel |
27.5 KB as written → 6.2 KB gzipped |
Vector; 360 hue wedges, each a 24-bit HEX fill | Plain-text XML, compressed in transit with gzip (DEFLATE: LZ77 + Huffman) |
Sizes measured from the files in assets/. “Raw bitmap” is width × height × 3 bytes, what the image costs in memory before any compression.