Free forever·no account, no tracking, no third-party requests ·open data, free API
showstack / learn / colour
Stage 1 of 7 · Foundations4 of 6 in this stage11 min read

How a colour becomes a number

Start with the question everybody actually asks. #ffffff is not a colour name — it is three bytes written in base 16, and they are the same three bytes a console sends to an RGB fixture. Once that lands, hex codes, DMX values and video code words stop being three separate subjects.

The direct answer

What #ffffff actually is

Three channels — red, green, blue — one byte each. A byte holds 0 to 255, and one byte is exactly two hexadecimal digits, which is the entire reason colours are written in base 16 rather than base 10: ff is unambiguous and two characters wide, where 255 is three characters and needs separators.

So #ff8800 is red 255, green 136, blue 0. Send those same three numbers down a lighting universe to an RGB fixture and you get the same instruction. A web colour and a DMX value are the same object arriving by different routes.

#fff is shorthand: each digit is doubled, so it expands to #ffffff. And #ffffff is every channel at maximum, which is why it is white — not because white is a colour, but because it is all three primaries at full.

Why 255 and not 100

Bit depth, again

Eight bits per channel gives 256 levels; three channels gives about 16.7 million combinations. That is 16.7 million codes, not 16.7 million distinguishable colours — the two are frequently confused in marketing.

Ten bits gives 1024 levels per channel and a bit over a billion codes. The reason to want that is not richer colour; it is gradients. A slow fade to black, a soft sky, a subtle wash across a large LED wall — these are where 256 steps become visible as bands, and where a large surface makes each step physically wide.

This is the same fact as bit depth in audio and 16-bit fixture control: resolution buys you steps small enough that nobody can see the join, and past that it buys storage.

blackwhite

The thing that surprises everyone

The numbers are not linear light

Half the code value is not half the light. Feed 128 out of 255 into a normal display and you get roughly 22% of the brightness of 255, not 50%.

That is deliberate. Human brightness perception is roughly logarithmic — we can distinguish far more steps in the dark than in the light, which is the dark adaptation story from the other side. If you spent 256 codes evenly on linear light, almost all of them would be wasted at the bright end where nobody can tell them apart, and the dark end would band horribly. So a transfer function is applied before storage that distributes the codes to match perception.

It is perceptual compression, and it is the only reason 8-bit video is watchable at all. It is also the source of a whole family of faults.

code value → light → linear

RGB is a recipe, not a colour

Which red is #ff0000?

The number says "the red primary, at full". It does not say what that primary is. Two displays with different red phosphors, different LEDs or different filters will both show you their maximum red, and those two reds will be visibly different colours.

A colour space is what closes that gap. It defines three things: the chromaticity of the primaries, the white point, and the transfer function. Given those, the same numbers mean the same colour on any display that honours them.

That is why a screenshot looks different on two monitors, why an LED wall needs calibration rather than just configuration, and why a camera, a media server and a wall all have to be told which space they are working in.

SpaceWhere it livesWhat to watch
sRGBComputers, the web, most graphics and content produced on a laptop.Effectively the same primaries as Rec.709 but a different transfer function definition. Close enough that people conflate them, and different enough to matter in a grade.
Rec.709HD broadcast and most show video. See BT.709.The safe default for a show, and the one everything else gets converted into when nobody has agreed anything.
DCI-P3Cinema projection, and increasingly high-end displays.Noticeably wider reds and greens than 709. Content mastered in P3 shown as 709 loses saturation; the reverse over-saturates.
Rec.2020UHD and HDR. See BT.2020.Wider than any current display can actually reproduce, so it is a container rather than a description of a screen.
Rec.2100HDR transfer functions — PQ and HLG. See BT.2100.PQ is absolute — a code means a specific brightness in nits. HLG is relative and degrades more gracefully on an SDR display.
rule
The numbers alone are meaningless. A colour is the numbers plus the space — primaries, white point and transfer function — and every hand-off between camera, server, processor and wall is a place that agreement can be lost.

The compression nobody mentions

Chroma subsampling

The eye resolves far more spatial detail in brightness than in colour. Video exploits that: RGB is converted into one luma channel plus two colour-difference channels, and then the colour channels are stored at reduced resolution.

The notation counts samples in a four-pixel-wide block. 4:4:4 keeps full colour resolution. 4:2:2 halves it horizontally. 4:2:0 halves it horizontally and vertically — a quarter of the colour samples, and half the total data.

For camera footage of the real world this is nearly invisible and enormously useful. For anything with hard colour edges it is not: text, fine graphics, and keying. Coloured text over a contrasting background at 4:2:0 develops visible fringes, and a green-screen key at 4:2:0 has a quarter of the edge information a clean key needs.

luma

every pixel, always

Brightness detail is kept in full because that is what the eye actually resolves.

chroma

every pixel

Full colour resolution — what you need for graphics, text and keying.

The fault that catches everyone

Full range against limited range

Computer graphics use the whole byte: 0 is black, 255 is white. Broadcast video does not — it puts black at 16 and white at 235, leaving footroom below and headroom above for signals that overshoot.

Both conventions travel down the same cable in the same eight bits, and nothing in the picture announces which one it is. Get it wrong in one direction and blacks are crushed and whites clipped; get it wrong in the other and the image is washed out and grey with no true black.

This is the most common video fault on a show, it looks like a grading problem rather than a signalling one, and the fix is a setting rather than a colour correction. When a laptop looks washed out on a wall that was fine yesterday, check this before anything else.

The round trip

Light in, numbers, light out

Everything above is the middle of a journey that starts and ends in the physical world.

Capture. Photons land on photodiodes and accumulate charge — the image sensor story. That charge becomes a voltage, an analogue-to-digital converter turns it into numbers, and those numbers are linear light at that point. Then the Bayer mosaic is interpolated into full colour, a matrix converts the sensor's native primaries into a standard space, and a transfer function is applied. Only after all of that do you have the numbers a file contains.

Display. The reverse, and the last step is physical again. The transfer function is decoded, the values are mapped onto the display's actual primaries, and something emits light. On an LED wall a driver chip switches each LED fully on and fully off very quickly — the LED has no dimmer — and the ratio between on and off is the level. On a DLP projector, micromirrors flip. On an LCD panel, liquid crystal modulates a backlight.

Which is why an LED processor talks about grayscale bit depth and refresh rate in the same breath: grayscale is how many on/off ratios the driver can produce, and refresh is how fast it repeats the pattern. Both are invisible to an eye and entirely visible to a camera — see genlock and LED walls and flicker fusion.

rule
Audio and video are the same story told twice. A microphone becomes numbers and a speaker becomes air; a sensor becomes numbers and an emitter becomes light. Sample rate and bit depth in one, resolution and bit depth in the other — and both are detours between two analogue events.
Want the arithmetic rather than the explanation?

The hex, gamma, range and bandwidth calculations on this page are tested functions embedded verbatim from test/tools.test.mjs, the same as everything in the field tools. The colour-space documents are in the standards index with access links.

Check yourself

2 questions on the mechanism rather than the trivia. Nothing is scored and you can answer again — the explanation under a wrong answer is the point of it.

  1. 1Why is #808080 not half as bright as #ffffff on a normal display?

  2. 2You are sending fine coloured text to an LED wall and it looks soft at the edges. Which is the most likely cause?

Answers are kept in this browser on this device. Nothing is sent anywhere.

You can now answer
  • What is a hex code?
  • Why is 128 not half brightness?
  • What is 4:2:0 costing me?
Kept in this browser on this device. Nothing is sent anywhere.

Where to go next

These pages are a chain rather than a library — the next one along usually answers the question this one raised.

Everything on this page, in the index

Each of these has its own entry with sources, ports, gotchas and an open gap where a field is missing.