edo1z blog

プログラミングなどに関するブログです

色の計算

色の計算がしたい。LESSとか使わないでちょっと計算できればプログラムにすぐ組み込める。色のことは全然詳しくないけど経験上FFBBCCとかあったらFの部分が赤くて、Bの部分が緑で、Cの部分が青というのは知ってる。あと数値が高ければ明るいこともしっている。あと、255,255,255と表現できることもしっている。あと6桁を3桁に省略できることも知っている。

color_bright($color, $per){}とかで、$colorの明るさを$perの割合に変更するプログラムが欲しい。0〜Fは16進数だから、00〜FFまでは確かに256個ある。10進数で表すと0〜255まである。16進数のカラー文字列を2桁ずつ区切りで赤、緑、青に分けて、10進数に直して、パーセントでかけてroundして、16進数に直して合体すれば終わりっぽい。

public function bright($color, $bright_per){
    $r = dechex( round( hexdec( substr( $color, 0, 2 ) ) * $bright_per ) );
    $g = dechex( round( hexdec( substr( $color, 2, 2 ) ) * $bright_per ) );
    $b = dechex( round( hexdec( substr( $color, 4, 2 ) ) * $bright_per ) );
    return $r . $g . $b;
}

ああでもよく考えたら暗いときは明るくすればいいけど、明るいときは暗くした方がいいっていうときもある。 それにFFFFFFの1.6倍の明るさというのは変だ。

public function bright($color, $bright_per){
    if($bright_per > 1) $bright_per = 1;
    if($bright_per < 0) $bright_per = 0;

    $new_color = array();
    $new_color[0] = hexdec( substr( $color, 0, 2 ) );
    $new_color[1] = hexdec( substr( $color, 2, 2 ) );
    $new_color[2] = hexdec( substr( $color, 4, 2 ) );

    $add = round(255 * $bright_per);
    if((($new_color[0] + $new_color[1] + $new_color[2]) / 3) > (255 / 2)) $add *= -1;

    foreach($new_color as $i => $c){
        $new_color[$i] = $c + $add;
        if($new_color[$i] < 0) $new_color[$i] = 0;
        elseif($new_color[$i] > 255) $new_color[$i] = 255;
        $new_color[$i] = sprintf('%02x', $new_color[$i]);
    }

    return implode($new_color);
}