このページの本文へ

PhotoshopのフィルターをJavaScriptで作る! (2/5)

2009年07月20日 12時36分更新

文●古籏一浩

  • この記事をはてなブックマークに追加
本文印刷

JavaScriptでピクセル値の読み書きを実現する

 Photoshop上でJavaScriptを動かす基本的な手順が分かったところで、今回のお題であるオリジナルのフィルターを作成する方法を検討してみましょう。

 フィルターを自作するには、画像データをピクセル単位で読み込み、何らかの変化を付けて書き込みし直す、というプログラムが必要です。ところが、PhotoshopのJavaScriptにはピクセル単位で書き込んだり、読み込んだりする命令は用意されていません。そこで少し発想を変えてみます。


●ピクセル単位の書き込み

 ピクセル単位での書き込みは、指定した座標を選択する命令と、指定した色で塗りつぶす命令を組み合わせます。1ピクセルの選択範囲を設定して塗りつぶす処理を1ピクセルずつずらしながら、繰り返していくのです。具体的には、以下のようなスクリプトになります(x,yは座標)。


RGBColor = new SolidColor();
RGBColor.red = 255;
RGBColor.green = 128;
RGBColor.blue = 0;
activeDocument.selection.select([[x,y],[x+1,y],[x+1,y+1],[x,y+1],[x,y]]);
activeDocument.selection.fill(RGBColor, ColorBlendMode.NORMAL , 100, false);

※画像モードはRGBモードを前提にしています。CMYKやLabカラーなど他の画像モードの場合は、設定するプロパティ名が異なりますので、付属のリファレンスを参照してください。



●ピクセル単位の書き込み

 次に、すでに書き込まれている色を読み出す方法を考えてみましょう。RGB/8ビットモードの画像は、Red(赤)、Green(緑)、Blue(青)のそれぞれの輝度(0〜255までの256段階)を合成してできています。そこで、Photoshopの「ヒストグラム」を使ってこの値を取得します。

 ヒストグラムは「分布図」の意味ですが、Photoshopのヒストグラムとは指定した選択範囲にピクセルの輝度がどのように分布しているかを表示/取得する機能です。Photoshopをお使いの方なら、レベル補正のときに表示される山型のグラフに見覚えがあるでしょう。画像が暗ければヒストグラムで表示されるグラフの山は左側に、明るければ山は右側に寄った形で表示されます。このグラフは、横軸が輝度、縦軸がピクセル数を表しています。

画像のヒストグラム

画像全体のヒストグラム

画像が暗い場合のヒストグラム。山は左側に寄っている

画像が明るい場合のヒストグラム。山は右側に寄っている


 ヒストグラムを画像全体ではなく、1×1ピクセルに範囲を指定して読みだすとどうなるでしょうか。当然、1ピクセルしかないので、0~255までの輝度に必ず1ピクセル分の輝度を示す値が存在することになります。0~255まで順番にピクセル数を調べていき、0以外の値が見つかればそれが色の輝度になります。この方法で、R、G、Bの3つのチャンネルについて調べていけば、ピクセル単位の色を読み出せる、というわけです。

 以下のヒストグラムは、画像のある1ピクセルを選択した状態です。1×1ピクセルなので全ピクセル数は1、中間値がピクセルの輝度を示しています。

画像の1ピクセルを選択し赤の成分を表示させたヒストグラム。赤の輝度は251というのがわかる

画像の1ピクセルを選択し赤の成分を表示させたヒストグラム。赤の輝度は251というのがわかる

画像の1ピクセルを選択し緑の成分を表示させたヒストグラム。緑の輝度は65というのがわかる

画像の1ピクセルを選択し青の成分を表示させたヒストグラム。青の輝度は88というのがわかる


 説明が少し長くなってしまいましたが、これで色を読み出す方法が決まりました。あとは実際にスクリプトを作成するだけです。R、G、Bの各チャンネルはchannels配列で、Photoshopのチャンネルパレットの順番と同じく、0番がR(赤)、1番がG(緑)、2番がB(青)となっています。

 ヒストグラムはhistogram配列に入っているので、0~255まで配列内容を調べていけばピクセルの輝度が取得できます。たとえばR(赤)の輝度は以下のようにして読み出せます。


data = activeDocument.channels[0].histogram;
for (i=0; i<256; i++) if (data[i] > 0) { R = i; break; }


 同様にしてG、Bも読み出します。RGB以外にアルファチャンネルが存在する場合は必要に応じて同様に読み出します。なお、読みだす輝度は、8ビットモードの場合は0~255ですが、16ビットモードでは0~65535になります。16ビットモードでは処理に膨大な時間がかかってしまい、ほとんど使い物にならないでしょう。

この連載の記事

一覧へ

この記事の編集者は以下の記事をオススメしています