【PHP実践|実務向け】PHPで実現する画像処理の基礎:RGBからHSVへの色空間変換

1. 導入

Web開発において、画像を扱う機能やカラーピッカー、あるいは「似た色を探す」といった検索機能を作成する際、RGB(赤・緑・青)形式のデータだけでは扱いにくいケースが多々あります。特に、人間の視覚的な感覚に近い「色合い(色相)」や「鮮やかさ(彩度)」を基準に処理を行いたい場合、RGBをHSV(色相・彩度・明度)に変換することが不可欠です。本記事では、PHPを用いてこの変換処理を正確に行う実装方法を解説します。

2. 基礎知識

RGBはコンピュータが色を表現する際の基本形式ですが、加法混色であるため、直感的に「色が似ているか」を計算するのには向きません。一方でHSVは以下の3要素で色を定義します。
H (Hue): 色相。0〜360度の範囲で色味を表します。
S (Saturation): 彩度。色の鮮やかさを0〜1(0〜100%)で表します。
V (Value): 明度。色の明るさを0〜1(0〜100%)で表します。
このHSVを用いることで、「色相は同じだが、少し明るい色」といった判定が容易になり、画像処理やデザインツールにおける高度な色操作が可能になります。

3. 実装/解決策

変換アルゴリズムは、RGBの最大値と最小値を基に計算します。まず各値を0〜1の範囲に正規化し、最大値と最小値の差から色相(H)を導き出します。注意点として、色相は円環状であるため、計算過程で負の値になった場合に360を加算して補正する処理が必要となります。

4. サンプルプログラム

以下は、RGB配列を引数として受け取り、HSV値を返す汎用的な関数です。

  • RGB配列をHSV配列に変換する関数
  • @param array $rgb [‘red’ => 0-255, ‘green’ => 0-255, ‘blue’ => 0-255]
  • @return array [‘h’ => 0-360, ‘s’ => 0-1, ‘v’ => 0-1]
  • /
    function rgb2hsv(array $rgb) {
    // 0~1の範囲に正規化
    $r = $rgb[‘red’] / 255;
    $g = $rgb[‘green’] / 255;
    $b = $rgb[‘blue’] / 255;

    $max = max($r, $g, $b);
    $min = min($r, $g, $b);
    $diff = $max – $min;

    // 明度(V)の決定
    $v = $max;

    // 彩度(S)の決定
    $s = ($max != 0) ? ($diff / $max) : 0;

    // 色相(H)の決定
    if ($diff == 0) {
    $h = 0; // 無彩色
    } else {
    if ($max === $r) {
    $h = 60 (($g – $b) / $diff) + 0;
    } elseif ($max === $g) {
    $h = 60 (($b – $r) / $diff) + 120;
    } else {
    $h = 60 (($r – $g) / $diff) + 240;
    }
    }

    // 色相が負の場合は360度を加算して補正
    if ($h < 0) $h += 360; return ["h" => $h, “s” => $s, “v” => $v];
    }

    // 実行例
    $rgb = [“red” => 167, “green” => 65, “blue” => 189];
    $hsv = rgb2hsv($rgb);

    echo “H: ” . round($hsv[‘h’], 2) . “度, “;
    echo “S: ” . round($hsv[‘s’], 2) . “, “;
    echo “V: ” . round($hsv[‘v’], 2);
    ?>

    5. 応用・注意点

    実務でこの計算を使用する際、浮動小数点数の演算誤差には注意してください。特に画像処理で大量のピクセルを変換する場合、計算結果を丸めすぎると色の再現性が低下します。また、HSVからRGBに戻す処理も必要になるケースが多いですが、その際は逆変換のアルゴリズムを別途実装する必要があります。
    また、HSVだけでなく、Webデザインではよく利用されるHSL(明度ではなく輝度をベースにする)との違いも理解しておくと、要件に合わせて最適な色空間を選択できるようになります。まずはこのコードをベースに、特定の色の範囲抽出などの機能へ応用してみてください。

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