Affichez une couleur, une palette, un dégradé ou une image dans tous les espaces colorimétriques. Des écrans à l’impression, des sélecteurs de couleur à la recherche, de 1860 à 2026.
Toute la bibliothèque : 221 espaces, 71 ko avec gzip – de n’importe quel espace vers n’importe quel autre, dans les deux sens.
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]]
Ou un seul espace – le bundle ne contient rien d’autre.
import oklch from 'color-space/oklch.js' oklch.rgb(0.65, 0.1, 180) // → [56.14, 162.97, 145.41]
Typé : les déclarations TypeScript sont livrées avec le paquet, pour toute la bibliothèque et pour chaque espace seul.
Pour des images entières et de longs tampons : 54 espaces, 53 ko avec gzip, 1.4 à 4.8× plus rapide que le traitement par lots en JS sur les 26 conversions mesurées.
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
Le module n’importe rien, il tourne donc partout où tourne WebAssembly : navigateurs, Node, Deno, Bun – et Python, Rust ou Go via wasmtime ou 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)
Espaces 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
Les 221 espaces en fonctions de shader. Une conversion vers rgb renvoie 0–255, comme en JavaScript : divisez par 255 pour une couleur de fragment.
WebGL et 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 et Unreal : HLSL. Metal : MSL. Tous deux générés à partir du WGSL par naga, une dépendance optionnelle.
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)Convertissez vos images dans votre logiciel de montage : choisissez deux espaces et téléchargez un .cube pour Resolve, Premiere, Final Cut, OBS ou ffmpeg. Les conversions des logs caméra concordent avec les transformations ACES officielles de l’Academy.
Utilisez un espace dans Photoshop, la gestion des couleurs de votre système, lcms ou ImageMagick : téléchargez-le en profil .icc. Les espaces RGB servent d’espaces de travail dans Photoshop ; les autres passent par une table de correspondance.
Pour les agents IA : ils appellent des conversions vérifiées au lieu de les deviner.
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"] } } }Remplissages et contours de la sélection dans n’importe lequel des 221 espaces – un plan et une barre par canal, limités au gamut du fichier ; copiez la couleur en CSS.
Toutes les couleurs du fichier – CSS, Swift, Flutter, Compose, Unity, design tokens – dans n’importe lequel des 221 espaces, avec un plan et une barre par canal ; chaque modification est réécrite dans la notation d’origine de la couleur.
Un système de coordonnées pour la couleur : des axes, des plages et une règle reliant les nombres à une lumière mesurable. La vision humaine est trichromatique, avec trois types de cônes (S, M, L) : il faut donc au moins trois coordonnées pour décrire toute couleur que l’œil peut voir. Le même orange s’écrit rgb(255 128 0), oklch(0.732 0.186 53) et XYZ [49, 36.7, 4.5]. Une palette est une poignée de couleurs choisies ; un espace permet d’écrire n’importe quelle couleur.
Un modèle de couleur définit les composantes utilisées pour décrire une couleur : trois primaires pour RGB, teinte, saturation et clarté pour HSL, quatre encres pour CMYK. Un espace colorimétrique précise les primaires, le point blanc et la courbe de codage. Chaque ensemble de valeurs correspond alors à une couleur mesurable. Ainsi, rgb(255 0 0) désigne des rouges différents en sRGB, Display P3 et Adobe RGB : un modèle, trois espaces.
Dans l’usage courant, les deux sont appelés espaces, y compris dans color-mix(in hsl, …) en CSS et dans ce catalogue. Un modèle peut prendre un espace existant comme référence : ici, HSL et HSV sont définis à partir de sRGB, comme en CSS.
Tout dépend de la tâche :
Pour voir tous les espaces classés par tâche, regroupez le catalogue par usage.
OKLCH. Il garde les trois mêmes réglages – teinte, chroma, clarté –, mais sa clarté est fiable : en HSL, le jaune à L=50 émet environ 13 fois plus de lumière que le bleu à L=50 ; un même L ne veut donc pas dire une même luminosité. En OKLCH, si. CSS prend en charge oklch() en natif.
Saisissez-la ou collez-la dans le champ de couleur en haut, par exemple #ff8000. Chaque espace de la page affiche aussitôt cette couleur ; en OKLCH, elle vaut 0.732, 0.186, 53, soit oklch(0.732 0.186 53) en CSS. L’onglet css de chaque fiche donne la forme à copier, et en code c’est space.rgb.oklch(255, 128, 0).
Parce qu’ils sont calculés en sRGB encodé en gamma, où moyenner les nombres de deux couleurs donne une lumière plus sombre et plus terne que le mélange réel de leurs lumières. Interpoler en OKLab l’évite ; en CSS, cela s’écrit linear-gradient(in oklab, red, blue). La ligne interpoler de chaque fiche trace le même dégradé dans deux espaces côte à côte : vous voyez la différence avant de choisir.
Ouvrez l’espace log de votre caméra, comme S-Log3, LogC4 ou Apple Log. Dans son bloc LUT, choisissez Rec. 709 et votre logiciel : DaVinci Resolve, Premiere Pro, Final Cut Pro, OBS, ffmpeg et d’autres. Votre navigateur génère le fichier .cube. C’est une conversion technique, sans mappage tonal : les hautes lumières au-dessus du blanc diffus sont écrêtées, et c’est à vous d’ajouter le look.
Une couleur qu’un espace peut décrire mais qu’un autre – ou votre écran – ne peut pas afficher. Un vert vif de Display P3 n’existe pas en sRGB : convertissez-le, et les nombres sortent de la plage valide. L’atlas le rend visible : un ⚠ près de la couleur courante signale qu’elle sort de la Limite choisie, Alt maintenu au-dessus d’un plan ou d’une bande indique le gamut plus large qu’exige une couleur à cet endroit (P3, Rec. 2020), et les tronçons hors plage apparaissent en transparence sur un damier.
Un écran émet de la lumière ; le papier réfléchit ce que ses encres n’absorbent pas. L’encre sur papier reproduit moins de couleurs vives – les bleus, verts et rouges RGB saturés lui échappent –, d’où une impression plus terne. Le prépresse convertit via un profil ICC établi pour la presse et le papier, comme FOGRA39 pour le couché européen ou GRACoL aux États-Unis. Le CMYK de ce catalogue est la formule simple qu’utilise CSS pour device-cmyk() sans profil : les valeurs sont exactes, mais ce n’est pas une épreuve de l’impression.
Pour le web et le partage, sRGB : navigateurs et téléphones l’appliquent par défaut quand un fichier n’embarque aucun profil. Display P3 restitue mieux les couleurs vives d’une scène sur les écrans Apple et sur de nombreux écrans Android, tant que le profil reste incorporé. Envoyez vos fichiers en Adobe RGB quand un laboratoire d’impression le demande. Réservez ProPhoto RGB à la retouche en 16 bits : son gamut est si large qu’en 8 bits les dégradés se postérisent.
Les conversions sont des formules analytiques, pas des approximations par table, et les allers-retours reviennent au point de départ au bruit du calcul flottant près. Les rares exceptions sont documentées là où elles surviennent : OSA-UCS n’a pas d’inverse analytique, et les systèmes d’atlas comme Munsell interpolent entre les échelons publiés. La sortie en rgb n’est jamais bornée : une couleur hors de sRGB revient sous 0 ou au-delà de 255, ne la bornez donc qu’à l’affichage.
Elles sont aussi vérifiées : chaque espace renvoie à l’article ou à la spécification qu’il implémente, les valeurs sont comparées à celles de colorjs.io partout où les deux se recoupent, et les logs de caméra aux transformations ACES officielles de l’Academy. formula-verification.md indique ce qui a été vérifié et par rapport à quoi, y compris quelques endroits où les articles publiés comportaient eux-mêmes des erreurs.
Si les nombres diffèrent de ceux d’une autre bibliothèque, comparez les plages : celle-ci garde les plages usuelles de chaque espace – RGB 0–255, clarté Lab 0–100, teinte 0–360 – là où beaucoup ramènent tout à 0–1. Chaque carte affiche ses plages ; dans le code, c’est space.oklch.range.
En natif : rgb(), hsl(), hwb(), lab(), lch(), oklab(), oklch(), plus color() pour Display P3, Adobe RGB, ProPhoto, sRGB linéaire et XYZ (D65 et D50). Le rec2020 de CSS est un gamma 2.4 pur, pas la courbe BT.2020 du Rec. 2020 de ce catalogue : les mêmes nombres y désigneraient une autre couleur. L’onglet css de chaque fiche donne la couleur courante sous une forme prête à copier ; les espaces absents de CSS sont fournis à la place en profils ICC ou en LUT.
Ouvrez Vue et choisissez une option sous Vision : aveugle au rouge (protanopie), aveugle au vert (deutéranopie) ou aveugle au bleu (tritanopie). Le catalogue se redessine tel que cet œil le voit, ce qui permet de vérifier que les couleurs d’une palette restent distinctes. Environ 1 homme sur 12 présente un trouble de la vision des couleurs, d’après les chiffres du NEI.
Ce sont des produits sous licence : leurs couleurs sont définies par des données que leurs propriétaires vendent, non par des formules publiées. Il n’y a donc aucune formule publique à implémenter, et redistribuer leurs tables serait illégal. Des systèmes voisins, dont les formules sont publiques, figurent ici : Munsell (sa renotation de 1943 a été publiée) et RAL Design (défini directement en CIELAB). Tout système dont les formules ont été publiées a sa place ici ; proposez-en un qui manque.
| Outil | Espaces | Logs de caméra | Luma–chroma | sRGB | Utilitaires | Taille | Vitesse | Cibles |
|---|---|---|---|---|---|---|---|---|
| 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 |
D’après le code source, le paquet ou la page de chaque projet, au 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
Caméras
2020, Sony
0.7442229873 0.0779065218 0.1283264179 0.280782476 0.7802857216 -0.0610681976 -0.0199292926 0.014796572 1.0941904714
Les images de la Venice en ACES – la propre matrice Venice de Sony à la place de la matrice S-Gamut3 générique.
Images de la caméra Venice de Sony enregistrées en S-Log3/S-Gamut3, via la transformation d’entrée ACES propre à cette caméra.
Sony n’a publié que la matrice vers ACES : les primaires sont déduites par un calcul qui suppose un blanc D65 et CAT02.
// one space, tree-shaken (0.4-1.5 kB) — its own edge: import sgamut3Venice from 'color-space/sgamut3-venice.js' sgamut3Venice.xyz(0.43, 0.43, 0.43) // → [20.5166, 21.5861, 23.5085] // any-to-any, both ways — the wired hub: import space from 'color-space' space['sgamut3-venice'].rgb(0.43, 0.43, 0.43) // → [128, 128, 128] space.rgb['sgamut3-venice'](128, 128, 128) // → [0.43, 0.43, 0.43] // route: sgamut3-venice → xyz → rgb