Colors API
Контраст WCAG, відтінки й тони для дизайн-токенів, гармонійні палітри (комплементарна, аналогова, тріадна) й вилучення домінантних кольорів — через один чистий REST-контракт.
Три ендпоінти для роботи з кольором: contrast — для аудиту доступності, shades — для дизайн-токенів і гармонійних палітр, extract — щоб вилучити домінантні кольори із зображення. Розрахункові ендпоінти працюють на чистому PHP і дають байт у байт той самий результат, що й наші вебінструменти; вилучення використовує Python-конвеєр, тож має такий самий суворий ліміт, як Images API.
# Check black-on-white contrast
curl "https://jinero.online/api/v1/colors/contrast?fg=%23000&bg=%23fff"
# Generate shades for a brand color
curl "https://jinero.online/api/v1/colors/shades?hex=%233b82f6&step=10"
const r = await fetch("https://jinero.online/api/v1/colors/contrast?fg=%23000&bg=%23fff");
const { ratio, aa, aaa } = await r.json();
Усі ендпоінти публічні — ключ не потрібен. Ліміти на один IP:
# Anonymous limits (per IP):
# GET /colors/contrast 60 req/min
# GET /colors/shades 60 req/min
# GET /colors/name 60 req/min
# POST /colors/extract 5 req/min (Python pipeline)
# Max image upload: 10 MB
# Max image_url fetch: 10 MB (server-side, image/* only)
Обчислює коефіцієнт контрасту WCAG 2.1 (за відносною яскравістю) між двома кольорами й повертає позначки відповідності AA/AAA для звичайного й великого тексту. Приймає #rgb, #rrggbb, rgb(...) або hsl(...).
https://jinero.online/api/v1/colors/contrast
| Параметр | Тип | Опис |
|---|---|---|
fg |
string | Колір тексту. Hex, rgb() або hsl(). |
bg |
string | Колір фону. Ті самі формати, що й для fg. |
curl "https://jinero.online/api/v1/colors/contrast?fg=%23000000&bg=%23ffffff"
# Equivalent with rgb()
curl "https://jinero.online/api/v1/colors/contrast?fg=rgb(0,0,0)&bg=rgb(255,255,255)"
const url = new URL("https://jinero.online/api/v1/colors/contrast");
url.searchParams.set("fg", "#1d4ed8");
url.searchParams.set("bg", "#ffffff");
const r = await fetch(url);
const data = await r.json();
if (!data.aa.normal) console.warn(`Ratio ${data.ratio_string} fails WCAG AA`);
$r = Http::get("https://jinero.online/api/v1/colors/contrast", [
"fg" => "#1d4ed8",
"bg" => "#ffffff",
]);
$ratio = $r->json("ratio");
{
"success": true,
"foreground": "#000000",
"background": "#ffffff",
"ratio": 21,
"ratio_string": "21.00:1",
"aa": { "normal": true, "large": true },
"aaa": { "normal": true, "large": true },
"thresholds": {
"aa_normal": 4.5,
"aa_large": 3,
"aaa_normal": 7,
"aaa_large": 4.5
}
}
Генерує повний набір дизайн-токенів з одного базового кольору: тони (світліші), відтінки (темніші) й п'ять гармонійних схем (комплементарна, аналогова ±30°, тріадна ±120°, розщеплена комплементарна, тетрадна). Кожен колір має рядки hex/rgb/hsl, відносну яскравість і рекомендований колір тексту.
https://jinero.online/api/v1/colors/shades
| Параметр | Тип | Опис |
|---|---|---|
hex |
string | Базовий колір. Hex/rgb()/hsl(). |
step |
integer | Крок у відсотках: 5, 10 (за замовчуванням), 20 або 25. |
limit |
integer | Обмеження кількості тонів/відтінків. За замовчуванням заповнює до 100% із заданим кроком (зазвичай 9 для step=10). |
curl "https://jinero.online/api/v1/colors/shades?hex=%233b82f6&step=20"
const r = await fetch("https://jinero.online/api/v1/colors/shades?hex=%231d4ed8&step=10");
const { base, tints, shades, harmonies } = await r.json();
// Drop into a design token map
const tokens = Object.fromEntries(
tints.map(t => [`brand-${100 - t.percent}`, t.hex])
);
$res = Http::get("https://jinero.online/api/v1/colors/shades", ["hex" => "#3b82f6", "step" => 20]);
$harmony = $res->json("harmonies.complementary.0.hex");
{
"success": true,
"step": 20,
"base": {
"hex": "#3b82f6",
"rgb": [59, 130, 246],
"rgb_string": "rgb(59, 130, 246)",
"hsl": [217, 91, 60],
"hsl_string": "hsl(217, 91%, 60%)",
"luminance": 0.2355,
"is_light": true,
"text_color": "#000000",
"contrast_on_white": 3.68,
"contrast_on_black": 5.71
},
"tints": [ { "percent": 20, "hex": "#629bf8", ... } ],
"shades": [ { "percent": 20, "hex": "#2f68c5", ... } ],
"harmonies": {
"complementary": [ { "rotation": 180, "hex": "#f6af3b", ... } ],
"analogous": [ { "rotation": -30, ... }, { "rotation": 30, ... } ],
"triadic": [ { "rotation": -120, ... }, { "rotation": 120, ... } ],
"split_complementary":[ { "rotation": 150, ... }, { "rotation": 210, ... } ],
"tetradic": [ { "rotation": 90, ... }, { "rotation": 180, ... }, { "rotation": 270, ... } ]
}
}
Отримайте найближчу зрозумілу назву для одного чи кількох кольорів — найближчий збіг (перцептивна відстань redmean) у наборі з ~31 тис. кольорів. Зручно для підписів до вилучених палітр, згенерованих зразків чи будь-якого hex.
https://jinero.online/api/v1/colors/name
| Параметр | Тип | Опис |
|---|---|---|
hex |
string | Один hex або кілька через кому (до 100), напр. #3b82f6,#000,#ff7f50. |
# Single
curl "https://jinero.online/api/v1/colors/name?hex=%233b82f6"
# Batch (comma-separated)
curl "https://jinero.online/api/v1/colors/name?hex=%233b82f6,%23000,%23ff7f50"
const r = await fetch("https://jinero.online/api/v1/colors/name?hex=" + encodeURIComponent("#3b82f6,#ff7f50"));
const { colors } = await r.json();
// colors: [{ input, name, hex, exact, distance }]
$r = Http::get("https://jinero.online/api/v1/colors/name", ["hex" => "#3b82f6,#ff7f50"]);
$name = $r->json("colors.0.name"); // "Dodger Blue"
{
"success": true,
"count": 3,
"colors": [
{ "input": "#3B82F6", "name": "Dodger Blue", "hex": "#3E82FC", "exact": false, "distance": 10.91 },
{ "input": "#000000", "name": "Black", "hex": "#000000", "exact": true, "distance": 0 },
{ "input": "#FF7F50", "name": "Coral", "hex": "#FF7F50", "exact": true, "distance": 0 }
]
}
Вилучає N головних кольорів із будь-якого зображення — завантаженого файлу або публічного URL. Працює на кластеризації k-means у трьох режимах: balanced, vibrant (надає перевагу насиченим барвам) і muted (надає перевагу приглушеним нейтральним). Кожен колір повертається з назвою (найближчий збіг) — готова підписана палітра за один виклик.
https://jinero.online/api/v1/colors/extract
| Параметр | Тип | Опис |
|---|---|---|
image |
файл (multipart) | Завантаження зображення — jpg, jpeg, png, webp, gif, bmp. До 10 МБ. Не можна поєднувати з image_url. |
image_url |
string | Публічний URL зображення, яке завантажить сервер (до 10 МБ, відповідь має бути image/*). |
count |
integer | Кількість домінантних кольорів у відповіді. 2–16, за замовчуванням 8. |
mode |
string | balanced (за замовчуванням) · vibrant · muted. |
# Option 1: file upload
curl -X POST https://jinero.online/api/v1/colors/extract \
-F "[email protected]" \
-F "count=6" \
-F "mode=vibrant"
# Option 2: URL fetch
curl -X POST https://jinero.online/api/v1/colors/extract \
-H "Content-Type: application/json" \
-d '{"image_url": "https://example.com/cover.jpg", "count": 6}'
// File upload
const form = new FormData();
form.append("image", file);
form.append("count", "6");
form.append("mode", "vibrant");
const r = await fetch("https://jinero.online/api/v1/colors/extract", { method: "POST", body: form });
const { colors } = await r.json();
// colors: [{ hex, rgb, hsl, percent, name, name_hex, name_exact }]
{
"success": true,
"mode": "vibrant",
"count": 6,
"colors": [
{ "hex": "#f9f9f9", "rgb": {"r":249,"g":249,"b":249}, "hsl": {"h":0,"s":0,"l":97.6}, "percent": 90.8, "name": "White", "name_hex": "#FFFFFF", "name_exact": false },
{ "hex": "#1d1c1b", "rgb": {"r":29,"g":28,"b":27}, "hsl": {"h":30,"s":3.6,"l":11}, "percent": 5.8, "name": "Cod Gray", "name_hex": "#1B1B1B", "name_exact": false },
{ "hex": "#a1989b", "rgb": {"r":161,"g":152,"b":155}, "hsl": {"h":340,"s":4.6,"l":61.4}, "percent": 1.9, "name": "Dusty Gray", "name_hex": "#A8989B", "name_exact": false }
]
}
Стандартна семантика HTTP. Помилки повертають JSON із полем "message".
// 422 — invalid color format
{ "message": "Invalid color format. Accepts #rgb, #rrggbb, rgb(r,g,b), or hsl(h,s%,l%)." }
// 422 — neither image nor image_url provided
{ "message": "Provide one of: image (file) or image_url." }
// 422 — URL fetch failed (404 from remote, non-image content, > 10 MB)
{ "message": "Could not fetch image from URL." }
// 429 — rate limit exceeded (5 req/min on extract)
{ "message": "Too Many Attempts." }
Про Colors API jinero.online
Безкоштовний REST API для всіх розрахунків кольорів: контраст WCAG, генерація відтінків і тонів, п'ять гармонійних палітр і вилучення домінантних кольорів (k-means) із будь-якого зображення.
Готовий до WCAG 2.1
Контраст рахується з тією самою лінеаризацією sRGB, що й у Google Lighthouse, — ваш CI для перевірки доступності погодиться з нашими цифрами.
П'ять вбудованих гармоній
Комплементарна, аналогова, тріадна, розщеплена комплементарна, тетрадна — усі обчислюються як повороти тону HSL від вашого базового кольору.
Зображення → палітра
Вилучення домінантних кольорів k-means у режимах vibrant / muted / balanced. Приймає завантажені файли або публічні URL.
Зручно для дизайн-токенів
Кожен колір повертається з hex, rgb, hsl, яскравістю й рекомендованим кольором тексту — додавайте одразу в мапу токенів.
Часті запитання
Ні. Ендпоінти контрасту й відтінків дозволяють 60 запитів/хв з одного IP. Вилучення кольорів важче (Python k-means), тож обмежене 5 запитами/хв. Для вищих лімітів зареєструйтеся й отримайте API-токен.
Hex із # або без (#rgb / #rrggbb), rgb(r,g,b) і hsl(h,s%,l%). Регістр не важливий. Перед розрахунками ми нормалізуємо колір до 6-символьного hex у нижньому регістрі.
Це той самий рушій — вебсторінка /colors/extract викликає той самий Python-скрипт (resources/python/color_extract.py). API лише додає JSON-обгортку й дає змогу передати image_url, щоб зображення завантажив сервер.
Рівні WCAG 2.1: AA для звичайного тексту — 4.5:1, AA для великого — 3:1, AAA для звичайного — 7:1, AAA для великого — 4.5:1. Ми повертаємо сам коефіцієнт і булеві позначки для всіх чотирьох перевірок, тож можна застосувати власні правила.
Ми обертаємо тон на колі HSL, зберігаючи насиченість і світлість. Комплементарна = +180°, аналогова = ±30°, тріадна = ±120°, розщеплена комплементарна = ±150°/210°, тетрадна = 90/180/270°. Інші інструменти (на основі LCH чи OKLCh) можуть давати інші кольори з тими самими назвами.