CanvasとJavascriptで画像処理 – 二階調化

前回は、CanvasとJavascriptで画像処理を行うための下準備として、canvas要素の導入とそのcanvasに対する画像の読み込みを行いました。

今回は、前回のコードをベースとして、読み込んだ画像を二階調化する処理を行いたいと思います。二階調化とは、画像の各ピクセルをその輝度に従い白か黒かどちらかの色に変換し、全体としてモノクロの画像にする処理です。

各ピクセルの色の取得

各ピクセルの輝度を算出するには、まず各ピクセルの色を取得する必要があります。その色は、0から255までの値をとるRGBの組み合わせで定義されています。例えば黄色であれば、赤と緑を混ぜ合わせるので(255, 255, 0)という具合です。

canvas上の各ピクセルの色を取得するには、canvasのcontextのgetImageData()メソッドを使用します。getImageData()はImageDataオブジェクトを返し、そのdata属性が各ピクセルのRGBの値を含んだ配列となっています。

getImageDataの引数は、取得する範囲の起点のx座標、y座標、幅、高さです。data配列は、一つ目のピクセルのR成分、G成分、B成分、透明度、二つ目のピクセルの…という順番で構成されているため、全体で画像の画素数の4倍の長さを持ちます。ピクセルの順番は画像の左上から右方向に一つずつ進み、右端まで行くと、二行目の先頭に戻る形で付けられます。

輝度の計算

輝度は色の明るさの指標の一つですが、RGBの単純平均ではなく、RGB各色に対する人間の視覚の感度を加味して計算されます。採用する色空間にも依りますが、以下の計算式が使われる場合が多いです。

二階調化

各ピクセルの輝度が計算できたので、これを閾値と比較して、大きければ白、同じか小さければ黒に変換します。閾値には、輝度の範囲0~255の中間である127が採用される場合が多いです。

全体のコード

以上を組み合わせると、CanvasとJavascriptでカラー画像を二階調化させるコードは以下になります。

計算した輝度に基づき、data配列のRGBを直接白(255, 255, 255)または黒(0, 0, 0)変更しています。最後に、data属性を更新したimageDataをputImageData()メソッドを使って再びcontextに反映させています。カラーのmono.jpg画像は、以下のような白黒画像に変換されると思います。

CORS (Cross-origin Resource Sharing)対応

上のコードをローカルPCで実行した場合、元のカラー画像がそのまま表示され、開発者ツール等で確認すると

といったエラーが表示されているかと思います。これはブラウザのクロスドメイン通信を拒否する実装によるものです。いやいや、どこのサーバーにもアクセスしていないだろうと思われるかもしれませんが、セキュリティ対策からすべてのローカルファイルは別オリジンであるとみなされます。

これを乗り越える方法としては、Google Chromeであれば「–allow-file-access-from-files」という起動オプションを付けて起動するという方法もありますが、一番手っ取り早いのは簡易サーバーをローカルPC上に立ててしまうことです。ローカルサーバーを立てるソフトウェアは色々ありますが、「Web Server for Chrome」というChromeのアドオンが非常に使いやすいと思います。

閾値の調整

二階調化は、画像の各ピクセルを単純に白か黒に変換するため、写真に適用させると上の画像のように原型が分からなくなってしまう場合が多いと思います。暗い色ばかりや薄い色ばかりで構成された画像はそれが顕著です。その場合、閾値の値を画像全体の輝度に合わせて調整すると良いと思います。単純に各ピクセルの平均をとる場合は以下のように行います。

少しはましになったでしょうか?

次回はグレイスケールについてお伝えしたいと思います。


“CanvasとJavascriptで画像処理 – 二階調化” への1件の返信

コメントは受け付けていません。