1. 導入:なぜカラー空間の変換が必要なのか
Web開発や画像処理において、色を扱う場面は少なくありません。しかし、ディスプレイで一般的に使われる「RGB」形式は、人間の色覚(明るさや鮮やかさの感覚)とは必ずしも一致しません。
例えば「類似画像検索」や「動的なカラーパレット生成」を行う際、RGBの数値だけで比較しても、人間が感じる「似ている色」を抽出するのは困難です。そこで、HSV(色相・彩度・明度)やLab(知覚的に均一な空間)への変換が重要になります。本記事では、PHPでこれらの変換を行うための実装方法を解説します。
2. 基礎知識:カラーモデルの役割
実装に入る前に、各カラーモデルの特性を理解しておきましょう。
RGB: 赤(Red)、緑(Green)、青(Blue)の3原色で表現する加法混色モデル。コンピュータで色を扱う際の基本です。
HSV: 色相(Hue)、彩度(Saturation)、明度(Value)で表現します。人間が「何色か(色相)」を直感的に操作するのに適しており、フィルタリング処理などで多用されます。
Lab(CIELAB): 人間の視覚特性に合わせて設計された色空間です。RGBやHSVとは異なり、数値上の距離が「人間が感じる色の差」とほぼ一致するため、高度な画像解析や色差計算に必須となります。
3. 実装と解決策
色空間の変換は数学的な計算を伴いますが、基本的には公式をコードに落とし込むことで実現可能です。RGBからLabへ変換する場合は、直接計算できないため「RGB → XYZ → Lab」という中間ステップを経由するのが一般的です。
4. サンプルプログラム
以下は、RGB値をLab値へ変換する実用的なコード例です。
/
function rgb2lab(array $rgb) {
// 1. RGBをXYZに変換
$xyz = rgb2xyz($rgb);
// 2. XYZをLabに変換
return xyz2lab($xyz);
}
function rgb2xyz(array $rgb) {
$r = $rgb[0] / 255;
$g = $rgb[1] / 255;
$b = $rgb[2] / 255;
// ガンマ補正を解除
$r = ($r > 0.04045) ? pow(($r + 0.055) / 1.055, 2.4) : $r / 12.92;
$g = ($g > 0.04045) ? pow(($g + 0.055) / 1.055, 2.4) : $g / 12.92;
$b = ($b > 0.04045) ? pow(($b + 0.055) / 1.055, 2.4) : $b / 12.92;
$r = 100; $g = 100; $b = 100;
// D50光源基準の変換行列
return [
$r 0.4360747 + $g 0.3850649 + $b 0.1430804,
$r 0.2225045 + $g 0.7168786 + $b 0.0606169,
$r 0.0139322 + $g 0.0971045 + $b 0.7141733
];
}
function xyz2lab(array $xyz) {
$ref_x = 96.422; $ref_y = 100.000; $ref_z = 82.521; // D50
$var_x = $xyz[0] / $ref_x;
$var_y = $xyz[1] / $ref_y;
$var_z = $xyz[2] / $ref_z;
$f = function($t) {
return ($t > 0.008856) ? pow($t, 1/3) : (7.787 $t) + (16 / 116);
};
$l = (116 $f($var_y)) – 16;
$a = 500 ($f($var_x) – $f($var_y));
$b = 200 ($f($var_y) – $f($var_z));
return [$l, $a, $b];
}
// 使用例
$rgb = [244, 46, 32];
print_r(rgb2lab($rgb));
?>
5. 応用・注意点
光源(イルミナント)の重要性
プログラム内で「D50」や「D65」という単語が出てきます。これは「どの光の下で見た色か」を定義する指標です。Web標準は通常「D65」ですが、印刷物やPhotoshopのカラーピッカーなどでは「D50」が使われることがあります。異なる規格を混ぜると色変換の精度が落ちるため、プロジェクト内で統一することが重要です。
パフォーマンスの考慮
大量の画像処理を行う場合、変換ロジックをループ内で何度も呼び出すとオーバーヘッドになります。可能な場合は、計算結果をキャッシュするか、一括処理ができるライブラリ(ImageMagickなど)の利用も検討してください。また、浮動小数点の計算誤差には注意し、必要に応じて丸め処理(round関数)を適宜挿入してください。