Перегляньте колір, палітру, градієнт або зображення в кожному колірному просторі. Від вебу до друку, від вибору кольору до досліджень, від 1860 до 2026.
Уся бібліотека: 221 простір, 71 КБ у gzip – з будь-якого простору в будь-який інший, в обидва боки.
npm install color-space
import space from 'color-space' space.rgb.oklch(255, 128, 0) // → [0.732, 0.186, 53] space.oklch.rgb(0.65, 0.1, 180) // → [56.14, 162.97, 145.41] space.oklch.range // [[0,1], [0,0.4], [0,360]]
Або один простір окремо – у збірку не потрапляє нічого зайвого.
import oklch from 'color-space/oklch.js' oklch.rgb(0.65, 0.1, 180) // → [56.14, 162.97, 145.41]
Типізовано: оголошення TypeScript входять до пакета – для всієї бібліотеки і для кожного простору окремо.
Для цілих зображень і довгих буферів: 54 простори, 53 КБ у gzip, у 1.4–4.8 раза швидше за пакетну обробку на JS на 26 виміряних перетвореннях.
import space, { alloc } from 'color-space/wasm'
space.oklch.rgb(0.72, 0.16, 41) // → [246, 125, 79]
const buf = alloc(n) // n×3 Float64Array
space.rgb.oklch(buf) // in place
Модуль нічого не імпортує, тож працює всюди, де працює WebAssembly: у браузерах, Node, Deno, Bun – а також із Python, Rust чи Go через wasmtime або wasmer.
import struct
from wasmtime import Store, Module, Instance # pip install wasmtime
store = Store() # color-space.wasm: the npm package's dist/
cs = Instance(store, Module.from_file(store.engine, 'color-space.wasm'), []).exports(store)
at = cs['alloc'](store, 1.0) & 0xFFFFFFFF # the buffer: n×3 float64 in the kernel's memory
cs['memory'].write(store, struct.pack('3d', 255, 128, 0), at)
cs['rgb_lrgb_n'](store, 1.0) # in place, edge by edge: rgb → linear rgb → oklab
cs['lrgb_oklab_n'](store, 1.0)
struct.unpack('3d', cs['memory'].read(store, at, at + 24)) # (0.732, 0.112, 0.148)
Простори rgb, lrgb, xyz, xyz-d50, xyy, lms, p3, p3-linear, rec2020, rec2020-linear, a98rgb, a98rgb-linear, prophoto, prophoto-linear, rec709, hsl, hsv, hwb, oklab, oklrab, oklch, oklrch, lab, lchab, lab-d65, lch-d65, din99o-lab, din99o-lch, luv, lchuv, hsluv, hpluv, cam16, hct, ycbcr-bt709, ycbcr-bt2020, jzazbz, jzczhz, ictcp, ictcp-hlg, ipt, din99d, acescg, acescct, acescc, awg3, logc3, logc4, slog3, vlog, log3g10, clog2, ryb, munsell
Кожен із 221 простору у вигляді шейдерних функцій. Перетворення в rgb повертає 0–255, як у JavaScript: для кольору фрагмента поділіть на 255.
WebGL і OpenGL: GLSL.
import { glsl } from 'color-space/gl'
import oklch from 'color-space/gl/oklch'
const frag = `#version 300 es
precision highp float;
${glsl(oklch, 'rgb')}
out vec4 color;
void main() { color = vec4(oklch_rgb(vec3(0.7, 0.15, gl_FragCoord.x)) / 255.0, 1.0); }`
WebGPU: WGSL.
import { wgsl } from 'color-space/gl'
const code = wgsl(oklch, 'rgb') + `
@fragment fn main(@builtin(position) p: vec4f) -> @location(0) vec4f {
return vec4f(oklch_rgb(vec3f(0.7, 0.15, p.x)) / 255.0, 1.0);
}`
DirectX, Unity і Unreal: HLSL. Metal: MSL. Обидва варіанти генерує з WGSL naga – необов’язкова залежність.
import { hlsl } from 'color-space/gl/hlsl' // npm i naga-wasm
import { msl } from 'color-space/gl/msl'
await hlsl('oklch', 'rgb') // float3 oklch_rgb(float3)
await msl('oklch', 'rgb') // metal::float3 oklch_rgb(metal::float3)Перетворюйте відзнятий матеріал у своєму редакторі: виберіть два простори й завантажте .cube для Resolve, Premiere, Final Cut, OBS або ffmpeg. Перетворення лог-кривих камер збігаються з офіційними перетвореннями ACES від Академії.
Перенесіть простір у Photoshop, системне керування кольором, lcms або ImageMagick: завантажте його як профіль .icc. Простори RGB працюють як робочі простори Photoshop; інші перетворюються через таблицю LUT.
Для ШІ-агентів: вони викликають перевірені перетворення, а не вгадують їх.
npx -y color-space mcp
// Claude Code
claude mcp add color-space -- npx -y color-space mcp
// VS Code
code --add-mcp '{"name":"color-space","command":"npx","args":["-y","color-space","mcp"]}'
// Claude Desktop · Cursor · .mcp.json
{ "mcpServers": { "color-space": { "command": "npx", "args": ["-y", "color-space", "mcp"] } } }Заливки й обведення виділення в будь-якому з 221 простору – площина і смуга на кожен канал, обрізані за охопленням файлу; колір можна скопіювати як CSS.
Усі кольори файлу – CSS, Swift, Flutter, Compose, Unity, дизайн-токени – у будь-якому з 221 простору, площина і смуга на кожен канал; зміна записується назад у тій самій нотації, якою заданий колір.
Система координат для кольору: осі, діапазони і правило, що пов’язує числа з вимірюваним світлом. Зір людини трихроматичний – колбочки бувають трьох типів (S, M, L), тому для опису будь-якого кольору, який бачить око, потрібно щонайменше три координати. Той самий помаранчевий – це rgb(255 128 0), oklch(0.732 0.186 53) і XYZ [49, 36.7, 4.5]. Палітра – це кілька вибраних кольорів; простір – спосіб записати будь-який колір узагалі.
Колірна модель задає, якими числами записують колір: RGB – трьома основними кольорами, HSL – колірним тоном, насиченістю і світлотою, CMYK – чотирма фарбами. Колірний простір прив’язує модель до вимірюваного світла – які основні кольори, яка точка білого, яка крива, – тож кожен набір чисел означає рівно один колір. rgb(255 0 0) – це різний червоний у sRGB, Display P3 і Adobe RGB: одна модель, три простори.
У повсякденному вжитку обидва називають просторами – так робить і CSS у color-mix(in hsl, …), і цей каталог. Модель, яка сама не прив’язана до вимірюваного світла, спирається на певний простір: HSL і HSV тут визначено через sRGB, як і в CSS.
Залежить від завдання:
Щоб побачити всі простори, впорядковані за завданнями, згрупуйте каталог за ознакою Призначення.
OKLCH. Він має ті самі три параметри – колірний тон, хрому, світлоту, – але його світлоті можна довіряти: у HSL жовтий при L=50 випромінює приблизно в 13 разів більше світла, ніж синій при L=50, тож однакове L не означає однакової яскравості на око. В OKLCH – означає. CSS підтримує oklch() безпосередньо.
Введіть або вставте його в поле кольору вгорі, наприклад #ff8000. Усі простори на сторінці одразу покажуть цей колір; в OKLCH це 0.732, 0.186, 53, а в CSS – oklch(0.732 0.186 53). Вкладка css кожної картки дає запис для копіювання, а в коді це space.rgb.oklch(255, 128, 0).
Бо їх обчислюють у гамма-кодованому sRGB, де усереднення чисел двох кольорів дає темніше й тьмяніше світло, ніж справжнє змішування їхнього світла. Інтерполяція в OKLab цього уникає; у CSS це linear-gradient(in oklab, red, blue). Рядок інтерполяція в кожній картці показує той самий перехід через два простори поруч, тож різницю видно ще до вибору.
Відкрийте лог-простір своєї камери, наприклад S-Log3, LogC4 або Apple Log. У його блоці LUT виберіть Rec. 709 і свій редактор: DaVinci Resolve, Premiere Pro, Final Cut Pro, OBS, ffmpeg та інші. Файл .cube створить ваш браузер. Це технічне перетворення без тонального відображення: світла понад дифузний білий обрізаються, а художній вигляд ви додаєте самі.
Це колір, який один простір може описати, а інший – або ваш екран – не може показати. Яскравого зеленого Display P3 у sRGB немає: перетворіть його, і числа вийдуть за допустимий діапазон. Атлас цього не приховує: значок ⚠ біля поточного кольору означає, що колір виходить за вибрану «Межу»; якщо навести вказівник на площину чи смугу з натиснутою клавішею Alt, підказка покаже, якого ширшого охоплення потребує колір у цьому місці (P3, Rec. 2020); а ділянки поза діапазоном напівпрозоро проступають поверх шахового тла.
Екран випромінює світло; папір відбиває те, чого не поглинули фарби. Фарба на папері відтворює менше яскравих кольорів – насичені сині, зелені й червоні кольори RGB лежать поза її охопленням, – тому на відбитку вони тьмяніші. Під час додрукарської підготовки кольори перетворюють через ICC-профіль, створений для друкарської машини й паперу, наприклад FOGRA39 для європейського крейдованого паперу або GRACoL у США. CMYK у цьому каталозі – проста формула, якою CSS обчислює device-cmyk() без профілю: числа вона дає правильні, але кольоропробою друку не є.
Для вебу та обміну – sRGB: браузери й телефони припускають саме його, коли файл не має профілю. Display P3 зберігає більше кольорів яскравої сцени на екранах Apple і багатьох Android, якщо профіль вбудовано у файл. Надсилайте Adobe RGB, коли його просить фотолабораторія. ProPhoto RGB залиште для 16-бітного редагування: його охоплення таке широке, що у 8-бітних файлах на градієнтах з’являються смуги.
Перетворення – це аналітичні формули, а не табличні наближення, і після прямого та зворотного перерахунку значення збігаються з точністю до похибки обчислень із рухомою комою. Нечисленні винятки зазначено там, де вони трапляються: OSA-UCS не має аналітичного оберненого перетворення, а системи-атласи на кшталт Munsell інтерполюють між опублікованими зразками. Вихід у rgb ніколи не обрізається: колір поза sRGB повертається зі значеннями нижче 0 або вище 255, тож обрізайте їх лише під час показу.
Їх також перевірено: кожен простір посилається на статтю чи специфікацію, яку реалізує; значення звіряються з colorjs.io скрізь, де бібліотеки перетинаються, а лог-криві камер – з офіційними перетвореннями ACES від Кіноакадемії. У formula-verification.md записано, що з чим звірено, зокрема кілька місць, де помилки були в самих опублікованих статтях.
Якщо числа відрізняються від результатів іншої бібліотеки, порівняйте діапазони: тут кожен простір зберігає свої усталені діапазони – RGB 0–255, світлота Lab 0–100, колірний тон 0–360, – тоді як багато бібліотек зводять усе до 0–1. Кожна картка показує свої діапазони; у коді це space.oklch.range.
CSS підтримує rgb(), hsl(), hwb(), lab(), lch(), oklab(), oklch(), а також color() для Display P3, Adobe RGB, ProPhoto, лінійного sRGB і XYZ (D65 і D50). rec2020 у CSS – це чиста гамма 2.4, а не крива BT.2020 простору Rec. 2020 у цьому каталозі: ті самі числа означали б інший колір. Вкладка css кожної картки записує поточний колір у формі для копіювання; простори, яких немає в CSS, можна завантажити як ICC-профілі або LUT.
Відкрийте Вигляд і виберіть Зір: сліпота до червоного (протанопія), до зеленого (дейтеранопія) або до синього (тританопія). Каталог перемальовується так, як його бачить таке око, і можна перевірити, чи не зливаються кольори палітри. Порушення колірного зору має приблизно 1 з 12 чоловіків, за даними NEI.
Це ліцензовані продукти: їхні кольори задано даними, які продають власники, а не опублікованими формулами, – тож відкритої математики для реалізації немає, а поширювати їхні таблиці було б незаконно. Близькі системи з публічною математикою тут є: Munsell (його ренотація 1943 року – загальнодоступний документ) і RAL Design (визначений безпосередньо в CIELAB). Будь-якій системі, математику якої колись опублікували, тут місце; запропонуйте ту, якої бракує.
| Інструмент | Простори | Лог-криві камер | Яскравісно-кольорорізницеві | sRGB | Інструменти | Розмір | Швидкість | Платформи |
|---|---|---|---|---|---|---|---|---|
| 205 | 31 | 16 | 0–255 | parse mix ΔE contrast CVD | 62 kB | JS, WASM, GL, LUT, ICC, OCIO, MCP, Figma, VS Code, CLI, web | ||
| 30 | – | 1 | 0–1 | parse mix gamut ΔE contrast CVD | 23 kB | JS | ||
| 51 | – | – | 0–1 | parse mix gamut ΔE contrast | 34 kB | JS, web | ||
| chroma-js | 11 | – | – | 0–255 | parse mix ΔE contrast palettes | 17 kB | JS | |
| @texel/color | 16 | – | – | 0–1 | parse gamut ΔE | 9 kB | JS | |
| 128 | 24 | 6 | 0–1 | ΔE CVD | – | – | Python, LUT | |
| 77 | – | – | 0–1 | parse mix gamut ΔE contrast CVD palettes | – | – | Python | |
| 9 | – | – | 0–1 | mix contrast CVD palettes | – | – | R, web | |
| 57 | 11 | – | 0–1 | gamut | – | – | C++, Python, GL, LUT, ICC | |
| 22 | – | – | 0–1, 0–255 | ΔE | – | – | web | |
| 9 | – | – | 0–255 | parse gamut | – | – | web |
За вихідним кодом, пакетом або сторінкою кожного проєкту, станом на 2026-10-18.
@software{Ivanov_color-space_2026,
author = {Ivanov, Dmitry},
license = {CC0-1.0},
month = oct,
title = {{color-space}},
url = {https://github.com/colorjs/color-space},
version = {3.4.0},
year = {2026}
}Ivanov, D. (2026). color-space (Version 3.4.0) [Computer software]. https://github.com/colorjs/color-space
Камери
Panalog → Linear-light sRGB → sRGB
2005, Panavision / Sony
Використовувалася лише в камері Panavision Genesis
Камерна лог-крива часів Genesis.
Цифровий кіноматеріал Panavision Genesis.
// one space, tree-shaken (0.4-1.5 kB) — its own edge: import panalog from 'color-space/panalog.js' panalog.lrgb(0.4, 0.4, 0.4) // → [0.2159, 0.2159, 0.2159] // any-to-any, both ways — the wired hub: import space from 'color-space' space.panalog.rgb(0.4, 0.4, 0.4) // → [128, 128, 128] space.rgb.panalog(128, 128, 128) // → [0.4, 0.4, 0.4] // route: panalog → lrgb → rgb