ForHosting KIT · Developer Utilities

Perceived brightness calculator

The perceived brightness calculator turns red, green, and blue channel values into one practical luminance score.

● BetaFree · in your browser
Use it from WebAPIEmailTelegramApp soon

It uses the familiar weighted RGB formula that gives green the greatest influence, red the next greatest, and blue the least. The result is classified as light or dark against a documented threshold, then paired with a suggested black or white text color. Use it when a theme, badge, chart, or user-selected background needs an immediate and repeatable foreground choice.

Why perceived brightness uses weighted RGB channels

A simple average treats red, green, and blue as if human vision responded equally to each channel. It does not. Green contributes much more to the brightness people perceive, red contributes a moderate amount, and blue contributes less. This calculator therefore applies the classic BT.601-style luma weights: 0.299 for red, 0.587 for green, and 0.114 for blue. Each channel must be an integer from 0 through 255. The weighted values are added to produce a score on the same approximate 0-to-255 scale, where black is zero and white is 255. The returned score is rounded to three decimal places so results remain readable while preserving useful precision. This operation is deterministic: identical RGB inputs always produce identical output, with no color profile lookup, network request, random choice, or device-specific adjustment. The calculation is especially useful for interface decisions that need a fast, understandable estimate rather than a complete color-management or accessibility analysis.

How the light or dark classification chooses text

After calculating perceived brightness, the capability compares the score with a threshold of 128. A score at or above 128 is classified as light, while a score below 128 is classified as dark. For a light background, the response recommends black text; for a dark background, it recommends white text. The output includes the original channels, the precise brightness score, the classification, the recommended text color, the threshold, and the formula, so an application can store or audit the decision instead of relying on an undocumented boolean. The boundary is intentionally explicit: a score of exactly 128 belongs to the light class. This makes behavior predictable around the cutoff and avoids slightly different results across clients. The recommendation is a convenient binary foreground choice for labels, chips, generated avatars, and theme previews. It is not a claim that every font size or visual treatment meets a particular accessibility standard; use a contrast-ratio checker when formal conformance is required.

Validate channels and use the result safely

Send the RGB components as the r, g, and b fields. Every field is required, must be numeric, must be a whole integer, and must remain within the inclusive range from 0 to 255. Values such as -1, 256, a fractional channel, a numeric string, NaN, or a missing field are rejected as invalid input rather than clamped silently. Strict rejection matters because clamping can hide upstream conversion bugs and make a saved design differ from its preview. Once a valid response arrives, use classification when only a light-or-dark branch is needed, or use recommended_text_color directly when the interface accepts a hexadecimal foreground. Use perceived_brightness when sorting swatches or exposing the calculation to users. The API costs $0.002 per request, while the deterministic browser path can run the same calculation locally. For large palettes, call the calculation once per color and retain the result alongside the source RGB values so later rendering does not need to guess how the decision was made.

Choose text for generated badges

Select black or white label text when badge backgrounds come from user data or generated palettes.

Classify theme swatches

Mark saved colors as light or dark so theme editors can preview sensible foregrounds immediately.

Audit automatic foreground decisions

Store the score, threshold, and formula with a design decision so its result can be reproduced later.

What formula does the calculator use?

It uses 0.299 × red + 0.587 × green + 0.114 × blue, with each channel in the inclusive range from 0 to 255.

When is a color classified as light?

A perceived brightness score of 128 or greater is light. Any lower score is dark.

Does this guarantee WCAG contrast compliance?

No. It provides a quick binary choice based on perceived brightness. Use a contrast-ratio checker for formal WCAG evaluation.

What happens when a channel is outside the valid range?

The request fails with an invalid input error. Values are never silently clamped into range.

How much does an API calculation cost?

Each API request costs $0.002. The browser version can perform the same deterministic calculation locally.

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.

POSThttps://api.kit.forhosting.com/color/luminance-perceived

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.

curl -X POST https://api.kit.forhosting.com/color/luminance-perceived \
  -H "Authorization: Bearer $KIT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"r":52,"g":152,"b":219}'
{
  "r": 52,
  "g": 152,
  "b": 219
}
{
  "task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
  "type": "color.luminance_perceived",
  "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.

Per request$0.002

Published price — no tokens, no invented credits. A failed task is never charged.

HTTPCodeMeaning
401unauthorizedMissing or invalid API key.
402insufficient_balanceYour balance doesn't cover the task price.
404unknown_typeThat task type doesn't exist.
429rate_limitedToo many requests. Use the webhook instead of polling.

Read the full KIT documentation →