マンセル表色系とRGBを相互変換する
(この記事は昔書いたものをほぼそのままコピペしたものです。)
マンセルからRGBへの変換方法を調べた上で、ColorMineという色変換ライブラリにマンセル表色系を追加してみた。
下調べ
変換式の参考サイト 名阪カラーワーク研究会 ミニ色彩講座(9)
マンセル Yxy値対応表 Program of Color Science / Munsell Color Science Laboratory ここのall.datかreal.datのどちらか、なんとなくだけどreal.datで良いっぽい。
上記対応表のYxy値を元にしてRGB変換を行えば良いんだが、Yxyから直接変換することはできなくてYxyの元の三刺激値XYZをまず求める必要があり、それを求めるには連立方程式を解かなければ…コードでどうやって?となってしまった。しかしやはり偉い人がいたようで…
yxy to xyz color conversion で検索したら一発で見つかった。色変換用のライブラリ。 https://github.com/THEjoezack/ColorMine
このColorMineライブラリを使えば、YxyからRGB変換も簡単にできる。 となれば後は表に対応してないマンセル値からどうやって近似値を求めるのかというロジックだけでOK。 ColorMineの中身を見ると色空間を追加しやすそうだったのでColorMineにマンセルを追加することにした。
近似値(補完値)を求める過程ではYxy表色系よりも均等色空間のLab表色系の方が適していて、さらにLabの彩度と色相を扱いやすくしたLch表色系の方が適している。ColorMineではLchにも対応しているので変換途中では全て一端Lchにして行うことにする。 変換表にもあらかじめ対応するLch値を追加しておく。
マンセル→RGB変換
手順(3R 6.5/7 の場合)
- 入力値の明度を切り上げした値を見込み明度とする(見込み明度7)
- 入力値を取り囲むであろう4値をマンセル対応表に存在する値より抽出 (2.5R 7/6、2.5R 7/8、5R 7/6、5R 7/8)
- 2のそれぞれに対応するLch値を求める
- 入力値と2の値とそのLch値の割合から入力値に対応するであろうLch近似値を求める
- 見込み明度と実際の明度の差の分だけLchのL*値を調整する
- 5のLch値をRGBに変換する
RGB→マンセル変換
- 入力値をLch変換
- マンセル対応表より1に最も近い値を抽出
- 色相角(h)が 2 < x < 1 または 1 < x < 2 の関係となる値も抽出
- 1~3の値の割合から入力値に対応するであろうマンセル近似値を求める
実装 (C#)
https://github.com/muak/ColorMine
- ColorSpaces / ColorSpacesMunsell.cs
- ColorSpaces / Conversions / MunsellConverter.cs
- ColorSpaces/ Conversions / Utility / MunsellTable.cs
の部分。クソコードですみません。
マンセルのついでに16進数コードの色空間も追加してみた。
ライブラリ公開中
nugetでColorMineを拡張したものを公開しています。 .net系で使用可能です。
PCL版
通常はこちらです。
https://www.nuget.org/packages/ColorMinePortable/
Install-Package ColorMinePortable
Xamarin.Forms対応版
こちらはXamarin.Formsに対応したバージョンです。
https://www.nuget.org/packages/ColorMinePortable.Forms/
Install-Package ColorMinePortable.Forms
使い方は以下の記事を参照してください。
注意事項
Yxy→RGBの変換過程で使用される係数は光源が標準光源D65 2度視野のもので固定です。 (ColorMineがその部分がハードコーディングされているため) かなり大雑把な変換のため変換後の値は正確ではありません。