SCSSのadjust-colorで明度を調整する処理をPHPのImageMagickで書き換える方法

この記事では、以下のことを説明します。

  • adjust-colorの明度とImageMagickにおける明度の関係の説明

上記について、かなり詰まったので備忘録です。

私が困ったこと

SCSSのadjust-colorで明度を変更するための処理として以下のコードがあるとします。

box-shadow: 0 3px 0 0 adjust-color(#FF0000, $lightness: -10%);

上記は、カラーコード#FF0000の明度を10%減らすという記述です。
SCSSのコンパイル時にadjust-colorが計算されて、コンパイル後のCSSには計算後のCSSが出力されます。

adjust-colorと全く同じようにPHPでカラーコードの変換を行おうとしました。

解決方法

ImageMagickクラスを使用することで解決しました。

コードは以下です。

function adjust_color($base_color, $lightness) {
  $color = new \ImagickPixel($base_color);
  $hsl = $color->getHSL();
  $colorInfo = $color->setHSL($hsl['hue'], $hsl['saturation'], $hsl['luminosity'] + $lightness);
  return arrayToRGB($color->getcolor());
}

function arrayToRGB(array $arr){
  return '#'.str_pad(dechex($arr['r']), 2, '0')
            .str_pad(dechex($arr['g']), 2, '0')
            .str_pad(dechex($arr['b']), 2, '0');
}

解説

引数は以下のように2つ用意します。
これはSCSSのadjust-colorと同じにしています。

  • $base_color・・・カラーコード
  • $lightness・・・明度(-1〜1までの浮動小数点数)
function adjust_color($base_color, $lightness) {

以下はカラーコードをコンストラクタに渡しています。
カラーコードの形式はImagickPixel::__constructを参考にしてください。
私は#XXXXXX形式で利用しています。

$color = new \ImagickPixel($base_color);

次に、RGB形式のカラーコードをHSL形式に変換します。
HSLは色相(Hue)、彩度(Saturation)、輝度(Lightness)で色を表す方式です。
詳細はググってみてください。

  $hsl = $color->getHSL();

次に、輝度に対して明度の変化を入れます。
明度が30%なら輝度に0.3を加算します。
明度が-10%なら輝度に0.1を減算します。

  $colorInfo = $color->setHSL($hsl['hue'], $hsl['saturation'], $hsl['luminosity'] + $lightness);

最後にカラーコードを返却します。
ImageMagickはカラーコードが配列になってしまっているので、#XXXXXXにするためにarrayToRGBメソッドで変換しています。

  return arrayToRGB($color->getcolor());

参考資料

Sass adjust-color() Function

ImagickPixel::setHSL