今日も適当ダイアリー

PHP や Javascript や Symfony、BEAR.Sunday などのWeb周りのことを中心に。それ以外のことも気まぐれに投稿します。

PHP配列とCSS色表現の相互変換

前回(色をアルファブレンドする - 今日も適当ダイアリー)にて、 relColors に使った使い回せそうな関数の公開を始めたのですが、ユーティリティ関数を書くのをすっかり忘れていました。

ということで、色テキスト表現からPHP配列の相互変換の関数を提示しておきます。

たいした事してないですけどね。
PHPで16進数テキストを integer にしたい場合は hexdec を使うとか、integer から16進表現にする場合は sprintf を使うとか、そこあたりは、よく忘れますよね。
初めてこの関数を聞いたっていう方は、頭の片隅においておくと、何かの時に便利かもと思います。

<?php

/**
 * 色表現テキスト(#rrggbb 形式) を配列形式に変換します
 *
 * @param   string  $str        色表現テキスト(#rrggbb 形式)
 * @return  array   array(r, g, b)
 */
function getColor($str)
{
    // 先頭の # を除去 (#rrggbb → rrggbb)
    if (strpos($str, '#') === 0) {
        $str = substr($str, 1);
    }

    // 先頭の 0x を除去 (0xrrggbb → rrggbb)
    if (strpos($str, '0x') === 0) {
        $str = substr($str, 2);
    }

    // 6 桁にそろえる
    switch (strlen($str)) {
        case 6:
            // 6桁ならそのまま
            break;
        case 3:
            // 3桁なら6桁に (rgb → rrggbb)
            $str = $str[0] . $str[0] . $str[1] . $str[1] . $str[2] . $str[2];
            break;
        default:
            // それ以外はNG
            return false;
    }

    $matches = array();
    // rrggbb を色事にキャプチャ
    if (preg_match('/^([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i', $str, $matches) != 1) {
        // rrggbb (それぞれは0~9 か a〜f) 以外ならNG
        return false;
    }

    return array(
        hexdec('0x' . $matches[1]), // (int) r
        hexdec('0x' . $matches[2]), // (int) g
        hexdec('0x' . $matches[3]), // (int) b
    );
}

/**
 * 配列形式 を 色表現テキスト(#rrggbb 形式) に変換します
 *
 * @param   array   $arr        array(r, g, b)
 * @param   bool    $compress   短い色表現(#rgb 形式) を許すか
 * @param   string  $prefix     プレフィックス (# 以外にしたい場合は指定)
 * @return  string  色表現テキスト(#rrggbb 形式)
 */
function getText($arr, $compress = true, $prefix = '#')
{
    // マイナス値が入っていたらNG
    if (min($arr) < 0) {
        return false;
    }

    // rrggbb 形式に変換 (integer 型に強制しておく)
    $tmp = sprintf('%02x%02x%02x', (int) $arr[0], (int) $arr[1], (int) $arr[2]);

    // 6桁にならない場合は失敗 (256以上が入っているとそうなる)
    if (strlen($tmp) !== 6) {
        return false;
    }

    // 短い色表現を許す場合で、
    // rr/gg/bb のそれぞれの上位と下位が同一であれば
    if ($compress
            && $tmp[0] == $tmp[1]
            && $tmp[2] == $tmp[3]
            && $tmp[4] == $tmp[5]) {
        // 3桁(rgb)にする
        $tmp = $tmp[0] . $tmp[2] . $tmp[4];
    }

    return $prefix . $tmp;
}

こんなもんです。