明るさ・鮮やかさを正確に評価したいなら、HSB/HSV/HSL色空間より、OKLCH色空間を使おう

# はじめに

背景色から文字色を決めるときや、色合いだけ変えたボタンを複数作りたい場合などに、どうやって決めていますか？
このような場合にはHSB（HSV/HSL）色空間を使うことが多いですが、実はそれでは正しく色を評価できないことがあります。

## 四角パネルの例

次の画像の左右のパネル背景色はどちらもHSB色空間の明度（Brightness）が同じ92です。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120077/9a22039b-847d-b3cf-a0cc-8b2276de2cba.png">

しかし左側の青パネルは黒文字が見づらく、右側の緑パネルは白文字が見づらいですよね？


|    空間    |    左    |    右    |
|:------------------:|:------------------:|:------------------:|
|    RGB    |    R:79 G:69 B:235    |    R:68 G:234 B:212    |
|    HSB    |    H:244 **S:71 B:92**    |    H:172 **S:71 B:92**	    |

明度(と彩度)が同じはずなのに、何故文字の見えやすさが変わってくるのでしょうか？
この投稿では、何故それが起きるのか？、そしてOKLCH色空間でこの問題を解決できることを示します。

# HSB色空間とは

先にHSB色空間について説明します。
HSB色空間では色を色相（Hue）、彩度(Saturation)、明度(Brightness)で色を表現します。
HSV色空間、HSL色空間も明度の呼び方が違ったり、単位が違うだけで本質的には同じなので、この投稿ではHSB色空間のみ書きます。

HSB色空間はRGB色空間と純粋な互換性があり、RGB空間を変形して軸を変えたものです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120077/47291fc8-43de-39bb-c831-0e777c96fa44.png)

RGBに比べて、HSBの方が色の指定がより人間にわかりやすく直感的に扱えますので、多くのペイントソフトなどのカラーパレットで採用されています。

## 明度（Brightness）が同じはずなのに？

さて、このHSB色空間は直感的に使えて便利ですが、一方で問題点も抱えています。

次の画像は横軸にH（色相）、縦軸にB（明度）を用いたカラーマップですが、同じ縦位置でも黄色と比べて青色が暗いことがわかると思います。


<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120077/7a24626f-bfd1-4957-1edf-153fb0a2685d.png">

これは、人間の視覚は色相によって明度・彩度の感じ方が変わるからです。

# OKLCH色空間とは

このようなHSB色空間の問題点を解決したのが、OKLCH色空間です。
OKLCH色空間では、明度（Lightness）、彩度（Chroma）、色相（Hue）で色を表現します。
ただし同じ名前の彩度や色相もHSB空間のそれとは異なり、人間の色覚を近似できるように設計されています。
以降では簡易的にLCHと記載します。

次の画像はLCH色空間の3Dモデルを3面図風にしたものです。

<img width="700" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120077/f55b79ae-0232-66d4-48e6-e3bb2217ae33.png">

HSB色空間の円筒形モデルとはかなり異なっていることが分かるかと思います。

## 四角パネル色をLCH色空間で表すと

このLCH色空間で最初の四角パネルの色を計算してみます。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120077/9a22039b-847d-b3cf-a0cc-8b2276de2cba.png">

|    空間    |    左    |    右    |
|:------------------:|:------------------:|:------------------:|
|    RGB    |    R:79 G:69 B:235    |    R:68 G:234 B:212    |
|    LCH    |    **L:51.47** C:0.238 H:276.64    |    **L:84.84** C:0.137 H:182.06    |

すると左が明度51.47、右が84.84とかなり差がありました。このため文字の見えやすさが左右で違うことが分かります。

## LCH色空間の範囲

RGB色空間はR,G,Bそれぞれが0～255の範囲で自由に設定でき、グラフで書けば指定範囲が立方体のようになっています。
HSV／HSB色空間も同様に指定範囲が円筒形のようになっています。

しかし、LCH色空間は前述のようにいびつな山脈ような形状で、H（色相）ごとにL（明度）、C（彩度）の取れる範囲が異なります。
このため、LCHの値の指定によっては存在しない色が指定できてしまいます。
次の画像は最初の画像の青四角パネルのLCH色空間でのグラフです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120077/cc44a55b-60d2-d089-5676-4faf390f997b.png)

右下のHue（色相）の項目がほとんど表示されていないのは、この色と同じC（彩度）をもつ色相が少ないことを示しています。

試しに、このLCH色空間のH（色相）だけ、最初の画像の緑四角パネルのH（色相）に変更すると、存在しない色を指定しているため、Fallbackと表示され、C（彩度）を下げた代替色が提示されてしまいます。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120077/0c41549a-2dc3-b058-45ac-435e9ff8abb3.png">

https://oklch.com/#51.47,0.238,160,100

逆に緑四角パネルの色を元に、色相だけ青四角パネルの値を指定しても存在しない色になってしまいます。

このようにLCH色空間はHSB色空間と比べて色を正確に評価できる代わりに扱いづらい側面があります。
LCH色空間も万能ではないので、すべての状況でLCH色空間が最適なわけではないです。

## 調整後の四角パネル色

LCH色空間を使って最初の画像の左右のパネルの色を両方調節したものがこちらです。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120077/2bfbad98-f70c-debd-ec5f-0be92c05f2dd.png">

元の画像に比べて左右ともに文字の見えやすさが同じになったことが分かるかと思います。

RGBとLCHの値が下記です。

|    空間    |    左    |    右    |
|:------------------:|:------------------:|:------------------:|
|    RGB    |    R:148 G:160 B:243    |    R:49 G:192 B:173    |
|    LCH    |    **L:73 C:0.12** H:276.6    |    **L:73 C:0.12** H:182.06    |

L（明度）とC（彩度）が両方の色で同じです。

調整前後の左右のパネルのLCH色空間のグラフへのリンクが以下です。

- 調整前
    - 左青 https://oklch.com/#51.47,0.238,276.64,100
    - 右緑 https://oklch.com/#84.84,0.137,182.06,100
- 調整後
    - 左青 https://oklch.com/#73,0.12,276.6,100
    - 右緑 https://oklch.com/#73,0.12,182.06,100

# LCH色空間の使用方法

LCH色空間はいくつかのツールを用いて使えます。

## OKLCH Color Picker & Converter

すでに何回も出てきた、OKLCH Color Picker & Converterのページを使えば、LCH色空間に基づいた色の設計ができます。
使いやすいですし、スライダーでL・C・Hのパラメータをグリグリ動かすことでLCH色空間の理解も深まります。

https://oklch.com/#73,0.12,276.6,100

## Apose Color converter

よりシンプルなColorConverterのページもあります。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120077/77a97699-37a5-794b-b612-5af5ef8bb04b.png">

https://products.aspose.app/svg/ja/color-converter/rgb-to-oklch

## HD Gradients

LCH色空間を使用したグラデーションを作成できるページです。
RGB色空間でのグラデーションと中間部分に灰色が混ざったりすることがありません。


[元画像の左右パネルの色のグラデーション](https://gradient.style/#type=linear&space=oklch&interpolation=shorter&linear_named_angle=--&linear_angle=129&stops=%7B%22kind%22%3A%22stop%22%2C%22color%22%3A%22oklch%2851.5%25+0.238+276%29%22%2C%22auto%22%3A0%2C%22position1%22%3A9%2C%22position2%22%3A9%7D&stops=%7B%22kind%22%3A%22hint%22%2C%22auto%22%3A50%2C%22percentage%22%3A50%7D&stops=%7B%22kind%22%3A%22stop%22%2C%22color%22%3A%22oklch%2884.8%25+0.137+182%29%22%2C%22auto%22%3A100%2C%22position1%22%3A99%2C%22position2%22%3A99%7D)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120077/edf34629-81e6-008f-3ee2-7daa12bce019.png)


## CSSでの実装

CSS Color 4でこのOKLCHは扱えるようになりました。

```css
a:hover {
  background:   oklch(45% 0.26 264); /* blue */
  color:        oklch(100% 0 0);     /* white */
  color:        oklch(0% 0 0 / 50%); /* black with 50% opacity */
}
```

## Adobe

AdobeではLCH色空間を使用したグラデーションが作れます。

https://helpx.adobe.com/photoshop/using/gradient-interpolation.html

## Figma

FigmaプラグインではLCH色空間のカラーパレットが使用できるようです。

https://www.figma.com/community/plugin/1173638098109123591/OkColor

# LCH色空間の詳細

## RGB⇔LCHの変換は一定ではない

RGB⇔LCHの変換時に指定する色温度によって変換後の値は変わってきます。
OKLCHでは一般にD65を使用しているようです。

## 他のLCH色空間

OKLCH色空間は2020 年にBjörn Ottossonによって提唱されました。
https://bottosson-github-io.translate.goog/posts/oklab/?_x_tr_sl=auto&_x_tr_tl=ja&_x_tr_hl=ja

それ以前にも、CIE LCH、Hunter LCHなどがありました。
基本的にはどれも同じような色空間ですが、細部の違いがあり、OKLCH空間が最新で最も扱いやすいと思います。

## 色域

LCHはRGBとの相互互換性が無いと書きましたが、逆に一般的なRGBのsRGBよりも広い、P3・Adobe RGB・Rec2020といった領域の色も表現できます。
したがって、CSSで `lch()` を使用して色を指定すれば、RGBよりも広い色を扱え、その色域に対応したディスプレイ・アプリを使用していれば、その色が表示されます。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120077/1c82f4fd-6b42-3293-0a7f-e03a20f0c969.png">

# まとめ

この投稿ではHSB色空間の欠点、LCH色空間の有用性、その使用方法について説明しました。
色を評価・設計するときにLCH色空間をぜひ使ってみてください。

# 参考

https://www.konicaminolta.jp/instruments/knowledge/color/section5/08.html

https://www.ccs-inc.co.jp/guide/column/light_color/vol14.html

http://www.brucelindbloom.com/index.html?Math.html

https://ja.wikipedia.org/wiki/Lab%E8%89%B2%E7%A9%BA%E9%96%93

https://triple-underscore.github.io/css-color-ja.html#lab-colors

https://evilmartians.com/chronicles/oklch-in-css-why-quit-rgb-hsl

https://bottosson.github.io/posts/oklab/