Under-color removal calculator for CMYK ink reduction
This under-color removal calculator transforms one CMYK color by finding the neutral amount shared by cyan, magenta, and yellow, removing a selected percentage of that overlap, and adding an equivalent amount of black within the valid CMYK range.
Run — free
It reports both the adjusted channels and the total ink before and after processing. The calculation is deterministic, validates every percentage, and makes the ink-saving effect explicit before the result reaches a print workflow.
What under-color removal changes
Under-color removal, commonly shortened to UCR, reduces the neutral portion built from overlapping cyan, magenta, and yellow inks and replaces that portion with black. A CMYK color such as a dark gray or shadow can contain substantial amounts of all three chromatic inks even when much of their combined visual role is neutral density. This calculator identifies the removable neutral component as the smallest of the three CMY percentages. That definition ensures the operation never drives a channel below zero. The chosen UCR percentage controls how much of that shared component is removed: zero leaves the color unchanged, while one hundred removes all of the available overlap. The same calculated amount is then added to the existing black channel, limited to the maximum valid black coverage. Because three channel contributions are reduced while at most one is added, the reported total ink decreases. The result is a mathematical ink-separation adjustment, not a prediction of an exact printed appearance on a particular press, paper, profile, or ink set.
How to enter and interpret CMYK values
Enter cyan, magenta, yellow, and black as percentages from zero through one hundred. These values should describe a single CMYK color before UCR is applied. Set the UCR percentage to the share of the common CMY component that should be replaced. A moderate setting retains more chromatic ink, while a stronger setting moves more neutral density toward black. The output repeats the adjusted CMYK channels and also exposes the neutral component, the amount removed from each CMY channel, and the amount actually added to black. Those last two values can differ when the input black channel is already near its upper limit: black is capped at one hundred, but the requested CMY reduction still proceeds, producing a larger total-ink decrease. Total ink before and after is the sum of the four respective channel percentages, often called total area coverage in production discussions. Use the precision option only to control displayed rounding; it does not change the underlying UCR calculation or permit values outside the validated ranges.
Using the result in a print workflow
Use this result as a deterministic planning value, comparison tool, or building block in an automated color pipeline. It is especially useful when evaluating how different UCR strengths affect total ink for the same source color. Compare several requests with identical CMYK inputs and different UCR percentages to see the tradeoff clearly. Before adopting any adjusted values for production, check them against the destination ICC profile, the printing process, substrate behavior, drying limits, and the printer's preferred separation strategy. Real color management may use more complex black-generation curves, gray component replacement, dot-gain compensation, and device-specific total-area-coverage limits. This calculator intentionally does not simulate those systems or claim colorimetric equivalence. Its narrow purpose is transparent and repeatable: remove equal amounts from the overlapping CMY channels, add black without exceeding its valid maximum, and show the resulting ink reduction. For automated use, the API returns named numeric fields that can be logged, compared, or passed to a later validation stage for each processed color item at $0.002 per request.
What you can do with it
Compare UCR strengths
Run the same CMYK color at several UCR percentages and compare the resulting channel values and total ink reduction.
Preflight a dark color
Estimate how replacing neutral CMY overlap with black changes total area coverage before applying device-specific production rules.
Automate separation calculations
Apply one documented, deterministic UCR rule to individual CMYK values in a repeatable processing pipeline.
FAQ
What does this calculator charge through the API?
Each API request costs $0.002. The same deterministic calculation is available free in the browser.
How is the removable neutral component calculated?
It is the smallest of the cyan, magenta, and yellow percentages, because that amount is present in all three channels and can be removed equally without making any channel negative.
Why does total ink decrease?
The operation removes the calculated amount from three CMY channels and adds it to at most one black channel, so the sum of all four channel percentages falls.
What happens when black is already close to 100 percent?
Black addition stops at 100 percent. The requested CMY removal still occurs, and the output reports the smaller amount actually added to black.
Does the result guarantee the same printed appearance?
No. Printed appearance depends on the output profile, press, inks, substrate, dot gain, and separation method. The result is a deterministic arithmetic UCR adjustment.
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/ucr \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"cyan":72,"magenta":64,"yellow":52,"black":18}'const res = await fetch("https://api.kit.forhosting.com/color/ucr", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"cyan": 72,
"magenta": 64,
"yellow": 52,
"black": 18
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/color/ucr",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"cyan": 72,
"magenta": 64,
"yellow": 52,
"black": 18
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/color/ucr", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"cyan":72,"magenta":64,"yellow":52,"black":18}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"cyan":72,"magenta":64,"yellow":52,"black":18}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/color/ucr", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"cyan": 72,
"magenta": 64,
"yellow": 52,
"black": 18
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "color.ucr",
"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.
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. |