ForHosting KIT · Developer Utilities

YIQ to RGB converter

This YIQ to RGB converter turns the luminance and two chrominance components used by the NTSC color model into practical red, green, and blue values.

● BetaFree · in your browser
Use it from WebAPIEmailTelegramApp soon

It applies a fixed inverse matrix, reports both normalized and 8-bit channels, and shows when a channel had to be clipped to the displayable RGB range. Strict validation catches missing, nonnumeric, infinite, and out-of-domain inputs before calculation. The conversion is deterministic, needs no network access, and produces the same result for the same Y, I, and Q components every time.

Enter normalized YIQ components correctly

Provide three numeric components: Y for luminance, I for in-phase chrominance, and Q for quadrature chrominance. Y must be between 0 and 1, I must be between -0.5957 and 0.5957, and Q must be between -0.5226 and 0.5226. These are normalized NTSC YIQ limits, not byte values and not percentages. A Y value near zero represents low luminance, while a value near one represents high luminance. The signed I and Q components carry color information around that luminance. Enter actual JSON numbers rather than numeric strings so the contract remains unambiguous across the API, SDKs, and browser form. The converter rejects missing values, strings, NaN-like values, infinities, and numbers outside the declared component ranges. That strict behavior prevents a typing or scaling mistake from producing an apparently plausible color. Aliases such as luminance, in_phase, and quadrature are accepted for integrations that use descriptive names, but y, i, and q are the canonical fields shown in examples and documentation.

Understand the inverse NTSC matrix and clamping

The calculation uses the fixed inverse transformation R = Y + 0.956I + 0.621Q, G = Y - 0.272I - 0.647Q, and B = Y - 1.106I + 1.703Q. Each equation first produces an unclamped normalized channel. Valid YIQ components can still describe a color outside the RGB cube because the legal YIQ region is not identical to the set of red, green, and blue combinations bounded by zero and one. For that reason, each raw output is clamped independently: values below zero become zero, and values above one become one. The converter preserves the pre-clamp values in unclamped_rgb and identifies every affected channel in clipped, so clipping never happens silently. It then multiplies each clamped normalized component by 255 and rounds to the nearest integer to create familiar 8-bit red, green, and blue channels. The same integer channels are formatted as a lowercase six-digit hexadecimal color and as a CSS rgb() value. Fixed coefficients and stable decimal rounding make repeated results predictable.

Read the result and use it safely

Use red, green, and blue when an application expects separate integer channels, rgb when it expects a three-element array, hex for design tools and color pickers, or css for a stylesheet declaration. normalized_rgb is useful in graphics code that consumes channels from zero through one. unclamped_rgb is diagnostic rather than directly displayable: it reveals what the matrix produced before gamut limiting. Check clipped whenever color fidelity matters. A clipped channel means the requested YIQ point falls outside displayable normalized RGB and the returned color is the nearest result under independent channel clipping, not an exact reversible representation. This distinction is important when analyzing legacy broadcast signals, porting image-processing formulas, or comparing implementations that use different coefficient conventions. Record the chosen matrix alongside stored results if another system may use a different YIQ definition. The endpoint performs one conversion per request and costs $0.002 through the API; the pure arithmetic has no network dependency, randomness, clock access, hidden state, or locale-sensitive formatting.

Decode legacy NTSC color data

Convert normalized luminance and chrominance samples from an archival or educational YIQ dataset into displayable RGB channels.

Verify a graphics implementation

Compare your inverse-matrix output, gamut clipping, hexadecimal formatting, and integer rounding against a deterministic reference result.

Inspect out-of-gamut colors

Use the unclamped values and per-channel clipping flags to see why a valid YIQ point cannot be represented exactly in the RGB cube.

What input ranges are accepted?

Y accepts 0 through 1, I accepts -0.5957 through 0.5957, and Q accepts -0.5226 through 0.5226. All three must be finite JSON numbers.

Which inverse matrix does the converter use?

It uses R = Y + 0.956I + 0.621Q, G = Y - 0.272I - 0.647Q, and B = Y - 1.106I + 1.703Q.

Why can valid YIQ input produce clipping?

The valid component ranges form a space that can extend beyond the normalized RGB cube. Raw channels outside 0 through 1 are clamped for display.

How are 8-bit RGB channels produced?

Each normalized channel is clamped to 0 through 1, multiplied by 255, and rounded to the nearest integer.

Is this conversion reversible?

It is reversible only when coefficient and rounding conventions match and no channel is clipped. Integer rounding also discards precision.

What does an API request cost?

Each request costs $0.002. The conversion processes one YIQ color item per request.

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/yiq-rgb

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/yiq-rgb \
  -H "Authorization: Bearer $KIT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"y":0.5,"i":0.2,"q":-0.1}'
{
  "y": 0.5,
  "i": 0.2,
  "q": -0.1
}
{
  "task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
  "type": "color.yiq_rgb",
  "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 →