Image color temperature adjustment
This image color temperature adjustment calculator turns an image’s average red, green, and blue values plus a Kelvin shift into three practical channel multipliers.
Run — free
It estimates the average color’s correlated color temperature, applies the requested warmer or cooler change, and reports normalized red, green, and blue gains. Use the result in a linear-light color pipeline to create a repeatable white-balance adjustment without uploading the image itself. The calculation is deterministic, transparent, and available for $0.002 per API request.
Prepare a representative average RGB value
Start with the arithmetic average of each 8-bit sRGB channel across the pixels you want the correction to represent. Supply those values as avg_r, avg_g, and avg_b on the familiar zero-to-255 scale. A whole-image average works for broadly illuminated photographs, product batches, thumbnails, and automated previews. For an image with a strongly colored subject, however, a neutral-region average may describe the illuminant more faithfully than the entire frame. A red wall or blue ocean can dominate a global average even when the camera white balance is already correct. The calculator does not inspect pixels, identify neutral objects, or distinguish lighting from subject color; it uses exactly the summary you provide. Fully black averages are rejected because they contain no chromaticity from which to estimate temperature. Values outside the 8-bit range and non-finite numbers are also rejected. Keeping the sampling method consistent across a batch is important: comparable averages produce comparable corrections, while changing masks or crop regions between images can make identical lighting appear different to the calculation.
Choose the Kelvin shift and understand the model
Enter shift_kelvin as a relative change, not an absolute destination. A positive value raises the estimated temperature and creates a cooler correction; a negative value lowers it and creates a warmer correction. Shifts from minus 10,000 through plus 10,000 Kelvin are supported, and the resulting target must remain between 1,000 and 40,000 Kelvin. The calculation first linearizes the average sRGB channels, converts them to CIE XYZ chromaticity, and estimates correlated color temperature with McCamy’s cubic approximation. It then evaluates deterministic blackbody RGB curves at the estimated and target temperatures. The ratio between those two white points becomes a set of channel gains, normalized so that green equals one. This is an engineering approximation rather than a spectral measurement. Correlated color temperature is most meaningful near the Planckian locus, so highly saturated averages can only provide a rough estimate. The returned method and temperatures make the assumption visible and let a processing pipeline record exactly how each gain set was produced.
Apply the multipliers without damaging the image
Apply red_multiplier, green_multiplier, and blue_multiplier to linear-light RGB values, not directly to gamma-encoded 8-bit channel numbers. A reliable workflow decodes sRGB to linear light, multiplies each channel by its corresponding gain, handles values above the display range with exposure adjustment or tone mapping, and then encodes the result back to sRGB. Multiplying encoded bytes directly may look plausible for a small shift, but it does not preserve the intended relationship between light and stored values. Green is normalized to one, so the result expresses chromatic balance rather than an overall exposure change. Red or blue may exceed one, and clipping can occur in bright areas; process with floating-point or sufficient bit depth before the final export. Preview the result on representative images before applying it to a large collection, especially when the average came from colorful scenery rather than a neutral reference. The API price is $0.002 per request, while the browser calculator can perform the same deterministic arithmetic locally without transmitting image pixels.
What you can do with it
Normalize a product-photo batch
Compute repeatable channel gains from the same average-color sampling method before exporting catalog images.
Prototype a white-balance control
Turn a Kelvin slider movement into explicit RGB multipliers for a browser or desktop image editor.
Record reproducible color corrections
Store the estimated temperature, target temperature, and gains beside an asset in an automated media pipeline.
FAQ
What does a positive Kelvin shift do?
It raises the estimated target color temperature, producing a cooler correction with relatively more blue and less red.
What range of shifts is supported?
The shift must be between -10,000 and 10,000 Kelvin inclusive, and the resulting target must stay between 1,000 and 40,000 Kelvin.
Why is the green multiplier always one?
The gains are normalized around green so they represent color balance independently of a separate exposure adjustment.
Should I multiply ordinary 8-bit RGB values directly?
No. Decode sRGB to linear light, apply the gains there, manage highlights, and encode the result back to sRGB.
How accurate is the estimated temperature?
It is an approximation based on average chromaticity. It works best when the sampled average represents neutral illumination and is less reliable for strongly saturated subject colors.
What does the API request cost?
Each API request costs $0.002. The browser version performs the same deterministic calculation locally for free.
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/image/color-temperature-adjust \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"avg_r":142,"avg_g":128,"avg_b":110,"shift_kelvin":1200}'const res = await fetch("https://api.kit.forhosting.com/image/color-temperature-adjust", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"avg_r": 142,
"avg_g": 128,
"avg_b": 110,
"shift_kelvin": 1200
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/image/color-temperature-adjust",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"avg_r": 142,
"avg_g": 128,
"avg_b": 110,
"shift_kelvin": 1200
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/image/color-temperature-adjust", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"avg_r":142,"avg_g":128,"avg_b":110,"shift_kelvin":1200}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"avg_r":142,"avg_g":128,"avg_b":110,"shift_kelvin":1200}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/image/color-temperature-adjust", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"avg_r": 142,
"avg_g": 128,
"avg_b": 110,
"shift_kelvin": 1200
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "image.color_temperature_adjust",
"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_shift_kelvin | -10000 |
max_shift_kelvin | 10000 |
min_temperature_kelvin | 1000 |
max_temperature_kelvin | 40000 |
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. |