【PHP実践|実務向け】PHPで実現するRGBからLab色空間への変換:実践ガイド

1. 導入

Web開発や画像処理の現場において、色情報を扱う機会は少なくありません。通常、WebではRGB値が使われますが、RGBは「デバイス依存」の色空間であり、人間の視覚に近い色差計算には適していません。そこで役立つのがLab色空間です。Lab色空間を使用することで、色の知覚的な距離を正確に測定できるようになります。本記事では、PHPを用いてRGB値をLab値に変換する実装方法を解説します。

2. 基礎知識

Lab色空間(Lab)は、国際照明委員会(CIE)が定義した色空間で、人間の視覚特性に基づいています。
Lは明度(明るさ)、aは赤から緑、bは黄色から青への成分を表します。
RGBから直接変換することはできないため、一度中間ステップとしてXYZ表色系を経由するのが一般的です。また、変換時には「標準イルミナント(基準となる光)」を指定する必要があります。今回はPhotoshopのカラーピッカー等でも採用されているD50(色温度5000K)を基準として扱います。

3. 実装/解決策

実装の流れは以下の3ステップです。
1. RGB値をsRGBの色空間で線形化する。
2. 線形化した値をXYZ表色系へ変換する(行列演算を使用)。
3. XYZ値をLab色空間へ変換する(非線形変換)。

特に3の手順では、値が一定の閾値を下回る場合に線形変換を行う特殊な計算が必要となります。これにより、暗い領域での色の変化を滑らかに表現できます。

4. サンプルプログラム

以下のコードは、RGB配列を入力として受け取り、変換後のLab値を配列で返す実用的な関数群です。

  • RGB値をLab色空間に変換する
  • /
    function rgb2lab(array $rgb): array {
    // 1. RGBをXYZに変換
    $xyz = rgb2xyz($rgb);
    // 2. XYZをLabに変換
    return xyz2lab($xyz);
    }

    function rgb2xyz(array $rgb): array {
    // 0-255の範囲を0.0-1.0に正規化
    $r = $rgb[0] / 255;
    $g = $rgb[1] / 255;
    $b = $rgb[2] / 255;

    // sRGBのガンマ補正を解除
    $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基準の変換行列を適用
    $x = $r 0.4360747 + $g 0.3850649 + $b 0.1430804;
    $y = $r 0.2225045 + $g 0.7168786 + $b 0.0606169;
    $z = $r 0.0139322 + $g 0.0971045 + $b 0.7141733;

    return [$x, $y, $z];
    }

    function xyz2lab(array $xyz): array {
    $ref_x = 0.96422;
    $ref_y = 1.0000;
    $ref_z = 0.82521;

    $var_x = $xyz[0] / ($ref_x 100);
    $var_y = $xyz[1] / ($ref_y 100);
    $var_z = $xyz[2] / ($ref_z 100);

    // 非線形変換(閾値判定)
    $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では変換行列の係数が異なります。用途が写真編集などであればD50、一般的なディスプレイ表示であればD65が適していますが、システム内で統一することが重要です。
    ・浮動小数点数:計算過程で多くの浮動小数点演算が発生するため、厳密な比較が必要な場合は微小な誤差を許容する判定(abs($a – $b) < 0.001など)を行ってください。 応用:
    この変換を応用すれば、データベースに保存された画像の色を解析し、「似た色」を持つ商品を検索するアルゴリズムや、画像内の主要色を抽出して自動的にCSSの配色を生成するといった高度な機能が実装可能になります。

    タイトルとURLをコピーしました