RGB to LAB converter
Move an RGB color into Lab, where lightness runs from 0 for black to about 100 for white and two axes carry the hue. It is the space used for delta-E distances and print targets. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Resistance (Ω)
- 255
- G
- 128
- B
- 0
- L
- 67.0548169961
- A
- 42.8260095268
- Lab b
- 74.0176483168
- L star
- 67.0548169961
This RGB to LAB converter takes three sRGB channel intensities—red, green, and blue—each as an integer from zero through two hundred fifty-five, and returns CIE L*a*b* coordinates computed with the standard D65 white point used in web and print color workflows. Designers, accessibility engineers, and students use this mapping when a palette lives in eight-bit channels but the task needs a perceptually uniform space for delta-E distances, contrast reasoning, or print-oriented Lab targets. The engine is fully deterministic: it inverse-compands each channel, multiplies by the D65 sRGB-to-XYZ matrix, normalizes by the D65 reference white, then applies the CIE Lab pivot and closed-form L*, a*, and b* identities—never calling the network, sampling randomness, or depending on the clock.
How an RGB color turns into Lab values
In the eight-bit sRGB model used by CSS and most web graphics, each of red, green, and blue is an integer channel from zero through two hundred fifty-five. CIE L*a*b* rearranges that same stimulus into a lightness axis L* (roughly zero for black through about one hundred for diffuse white) and two chromatic axes: a* runs green-negative to red-positive, and b* runs blue-negative to yellow-positive.
Conversion first scales each channel by dividing by two hundred fifty-five, then undoes sRGB gamma (the IEC six-one-nine-six-six inverse companding curve) so the values become linear light. Those linear channels pass through a fixed three-by-three matrix into CIE XYZ under illuminant D65; each tristimulus component is divided by the D65 reference white, then the CIE pivot function f is applied—cube root above a small threshold, linear branch below—to form L*, a*, and b*.
There is no path that accepts percentages or floating-point channels as input, and no silent clamp of two hundred fifty-six down to two hundred fifty-five.
Where RGB-to-Lab conversion fits in design, study, and software
Designers meet this mapping when a brand guide lists RGB swatches and a production or print workflow expects Lab targets, when two colors must be compared with a simple Euclidean distance in a roughly uniform space, or when a design system documents both screen RGB and Lab reference values side by side.
Accessibility engineers use L* and chromatic axes when reasoning about perceived lightness separately from hue, when checking that two UI states are far enough apart for users with low vision, or when preparing notes that will later feed formal delta-E checks. Students see it in computer-graphics and color-science courses that introduce XYZ and Lab after sRGB, in digital photography classes that move between channel sliders and Lab adjustments, and in interview warm-ups that ask for a mental convert of a short triple.
Pair it with multi-format color tools when you need hex or CMYK, and with other free deterministic converters when you are building a small lab for design-system hygiene.
What you can do with it
Perceptual color distance and tokens
Turn brand RGB triples into CIE L*a*b* for delta-E style checks, design tokens, and print-oriented Lab references.
Homework and teaching demos
Check student sRGB-to-Lab work and live-demo XYZ and D65 Lab without opaque calculator apps.
FAQ
What does the RGB to LAB converter cost?
It is free in your browser on this page.
What range is allowed for r, g, and b?
Each channel must be an integer from 0 to 255 inclusive.
What Lab values does orange 255, 128, 0 give?
L* 67.0548169961, a* 42.8260095268 and b* 74.0176483168, under the D65 white point. The positive a* leans toward red and the large positive b* toward yellow.
What do a* and b* mean?
They are the two color axes. a* runs from green when negative to red when positive, and b* from blue when negative to yellow when positive; L* is the separate lightness axis.
Which white point is used?
D65, the standard daylight reference used in web and print color work. Every result is computed against that white, so compare it with Lab values that also use D65.
Why use Lab instead of RGB to compare two colors?
Lab is roughly perceptually uniform, so a simple straight-line distance between two colors says more about how different they look. That idea is the basis of delta-E checks.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/color/rgb-lab \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"r":255,"g":128,"b":0}'const res = await fetch("https://api.kit.forhosting.com/color/rgb-lab", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"r": 255,
"g": 128,
"b": 0
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/color/rgb-lab",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"r": 255,
"g": 128,
"b": 0
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/color/rgb-lab", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"r":255,"g":128,"b":0}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"r":255,"g":128,"b":0}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/color/rgb-lab", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"r": 255,
"g": 128,
"b": 0
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "color.rgb_lab",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
min_channel | 0 |
max_channel | 255 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
Channels outside zero through two hundred fifty-five are rejected with a clear invalid_input error rather than silently clamped.
What RGB-to-Lab conversion means and what the response contains
This calculator returns the validated integers r, g, and b, rounded L and a for L* and a*, lab_b and b_star for b* so the Lab blue-yellow coordinate never collides with the RGB blue channel field, intermediate X Y Z, an rgb function string, a lab summary string, white_point set to D65, a method tag rgb_to_lab, and a short formula reminder. The engine either builds an exact Lab triple for three legal channels or rejects the request with invalid_input. Rejected cases include a missing r, g, or b field, empty strings after trimming, non-integer numbers, non-numeric text, Infinity or NaN, and any channel strictly below zero or above two hundred fifty-five.
How r, g, and b are read and how Lab stays reproducible
Outer whitespace on string channels is trimmed; an optional leading plus is allowed only when the remaining characters are decimal digits that parse to an integer in range. A bare JavaScript number is accepted only when it is a finite integer inside zero through two hundred fifty-five; values such as one hundred twenty-eight point five fail validation rather than being rounded, and negative or two-hundred-fifty-six-plus values fail with a message that names the channel and states that it must stay inside zero through two hundred fifty-five. Pure red maps to a moderate L* with large positive a* and b*; pure white maps to L* near one hundred with near-zero a* and b*; pure black maps to zero on all three Lab axes. The preferred fields are r for red, g for green, and b for blue, but aliases red and capital R for red, green and capital G for green, and blue and capital B for blue are accepted so spreadsheets, query strings, and typed forms can reuse the same contract without renaming columns. After validation, conversion uses only closed-form arithmetic on the linear channels and the D65 white point, then rounds floating components to a fixed decimal width so JSON goldens and CI assertions stay stable across platforms. Pair the free browser run on this page with the priced API when you need the identical mathematical result inside an automated pipeline without re-implementing inverse gamma and D65 normalization yourself.
Where RGB-to-Lab conversion fits in design, study, and software
On this page the work runs entirely in your browser; through the API each successful lookup costs $0.002, failed validation is not charged, and nothing is stored after the response returns. That split—free interactive exploration and a priced, identical API—matches the rest of the KIT tier-A catalog and lets you move from a classroom demo or design review to an automated pipeline without changing the mathematical result.
Integration use cases
Deterministic test fixtures
Generate reproducible Lab results for unit tests, property checks, and CI assertions on color helpers.
Technical questions
What white point does this use?
Illuminant D65 with reference white Xn=0.95047, Yn=1.0, Zn=1.08883, matching standard sRGB and web color practice. The response includes white_point: "D65".
Why is Lab b* called lab_b or b_star?
The input field b is the blue RGB channel. Lab b* is returned as lab_b and b_star (and inside the lab string) so it never overwrites the validated blue channel.
Why is 256 rejected instead of clamped?
Silent clamping hides data errors. Out-of-range channels fail with invalid_input so callers fix the source values instead of publishing the wrong color.