necotech blog

HTML5 Canvasで色相変換

Canvas上で、画像の色相変換をやってみました。
画像の色相変換

色相とは?

色相(しきそう、英: hue[1])は、赤、黄、緑、青、紫といった色の様相の相違である。特定の波長が際立っていることによる変化であり、際立った波長の範囲によって、定性的に記述できる。ただし、常に同じ波長が同じ色に見える訳ではない。赤から、黄、緑、青を経て、菫(紫)までは、スペクトル上の色であると言える。

色相 – Wikipedia

色合いとか、色味といった言葉の方が日常的には馴染みがあるかもしれません。つまり、赤とか青とかの色情報は数値として表すことができる、という話です。

余談ですが、この辺の情報も合わせて調べると興味深いです。
人間は、特定の波長を色として感じることができます。-色色雑学 | コニカミノルタ

HSV

色をコンピュータ上で表現する方法としては、RGBがメジャーです。ディスプレイ自体も、実際にRGBを使って表示するものが多数です。(RGBとディスプレイ)

では、色相を使って特定の色を表現するにはどうすればいいか。色相はあくまで「色合い」を表しているだけで、他に彩度明度を情報として持たせる必要があります。この3つの属性を数値にして表現した色を、HSVと呼びます。

RGB <=> HSV変換

前置きが長くなりましたが、要は色をHSVで表現し、H(色相)だけを変更すれば、色相変換が実現できるという訳です。しかし、Canvasの「色の表現方法」も例に漏れずRGBなので、まず、RGBとHSVを相互変換する仕組みを作る必要があります。この辺は検索して出てきた情報を参考にコーディング。画像の色相変換では、変換用の関数を2つ用意しました。

ImageData

Canvas上に出力されている画像データは、ビットマップとして配列で取得することができます。

var data = ctx.getImageData(0, 0, width, height);

このデータ(ImageData)からビットマップ情報をforでぶん回すことで、各ピクセルの色情報をRGBで取得できます。

for(var i=0; i<=width*height*4; i+=4){
  r = data.data[i];
  g = data.data[i+1];
  b = data.data[i+2];
  // alpha = data.data[i+3];
  ...
}

後はHSVに変換し、H(色相)の値を変更後、RGBに再変換、その色をCanvasに描画すれば完了です。簡単なコードなのですぐ読めると思います。

これは何に使える?

色違いの同じ画像を、一つの画像から複数生成することができます。たとえば、花火や光のエフェクトの量産、2Pカラーなど。彩度を変えれば、グレースケールにしたり、アニメーションでグレーアウトさせたり。

ハマりそうな点

getImageDataは、外部ドメインから取得した画像の描画が含まれていたらセキュリティエラーになります。

[参考]
Canvas関連のプログラムをしていたときに発生するセキュリティエラー Security error" code: "1000 の意味 – 強火で進め
HTML5 CanvasのcreateImageDataで注意 | TechRacho

Access-Control-Allow-Originヘッダを使えば解決できる?気がしますが未検証です。
他には、サーバ側で外部から画像を取得・表示するWeb Proxyを作ればどんな画像も扱えますが、本末転倒なのでおすすめできません。ホワイトリスト形式での実装や、テスト用/ローカル用にはいいかもです。

その他、今回作ったスクリプトで改良できる点

色相変換が実現できましたが、同様の手順で彩度・明度も変更することができます。あとは、最初の画像の描画は表示する必要がないので、場合によってはダブルバッファを検討してもいいかもしれません。

Facebook にシェア
LinkedIn にシェア
Pocket