Top > ScriptFuClass > Step5

CENTER:[[四限目>ScriptFuClass/Step4]] | [[Script-Fu 青空教室>ScriptFuClass]] | [[放課後>ScriptFuClass/After]]

-----

* 五限目 実践的なスクリプト [#a2bfb929]

#contents


三限目では、スクリプトを書き上げるまでの基本的な流れを説明しました。しかし、実践的なスクリプトを実際に書こうとすると、いくつか考えなければならない事やテクニックが必要になってきます。ここでは Script-Fu をさらにステップアップさせるためのチップが書かれています。


** 5.1 画像依存型スクリプトで考慮すべきこと [#md4fd359]

独立実行型スクリプトでは、自分で最初から画像を作っていくので初期条件は自分で決めることができます。それに対し、画像依存型スクリプトを実行する時、実行した時の状態についても考慮しなければならない場合があります。

どのようなことについて注意しなければならないかについて、リストアップしてみます。

:1. 対象がレイヤーなのか、レイヤーマスクなのか、チャンネルかなのか、あるいはインデックスか|これはスクリプトの性格によって異なります。script-fu-register の許可する画像のタイプで全てを受け入れられるようにするのが望ましいでしょうが、画像に対して処理を行う大抵のスクリプトの場合、RGB* や GRAY* になるでしょう。GRAY の場合ではレイヤーマスクやチャンネルに対してスクリプトを適用しても問題ないかどうかがポイントになります。これらに対してレイヤーマスクを追加するような操作は行えません。

:2. レイヤーマスクがある場合はどうするか|上の条件に重なりますが、画像の種類に RGBA と GRAYA を許可する場合はレイヤーマスクが存在するケースも考えられるので、その場合はどうするのかを決めなければなりません。"レイヤーにレイヤーマスクが存在する場合は適用" するということを予め行ってから実際のスクリプト処理を行うようにすれば問題ないでしょう。

:3. 透明領域はどうするか|RGBA や GRAYA や INDEXEDA では、アルファチャンネルを持つことができます。特に、中間調のアルファ度を持つことができる RGBA と GRAYA では、完全に不透明な状態と比較して、透明部分の処理結果が違うということがよく発生します。透明部分がどうなるかを見極めながら処理を行うようにします。

:4. 選択領域をどうするか|画像に選択領域が存在する場合、ぼかしフィルターを行うと選択領域内だけがぼかされます。これと同じように、画像に選択領域がある状態でスクリプトを実行するとどうなるのかについても考慮しなければなりません。最初に gimp-selection-none で選択領域を消去してしまうのも一手ですが、できればこれを避け、アクティブな選択領域がある場合はその選択領域内だけに効果があるようにした方が良いでしょう。 

通常これらは全てを考慮する必要が無いかもしれませんが、自分が今作りたいスクリプトの目的をよく考え、これらのことを念頭に置きながら開発を進めるようにしましょう。


** 5.2 入力ボックスの引数型 [#v1a534ff]

スクリプト中でパターンやグラデーションを使いたい場合、スクリプトを実行するときにユーザーが入力ボックスでパターンやグラデーションを選択できるようにしなければいけません。この入力ボックスに使用できる引数型の説明をしていきます。

*** 5.2.1 入力ボックスに使用できる引数型 [#e13327bd]

入力ボックスに使用できる引数として、以下の表にあるものが使えます。個々の詳しい説明はこの後でします。これらを必要に応じて用いることで、ユーザーにダイアログで指定させることができるようになります。

表: Script-Fu で使用できる引数型

|~引数型|~説明|~データの種類|~データ例|
|SF-IMAGE|画像を選ばせる|整数|0|
|SF-DRAWABLE|ドロアブルを選ばせる|整数|0|
|SF-LAYER|レイヤーを選ばせる|整数|0|
|SF-CHANNEL|チャンネルを選ばせる|整数|0|
|SF-VECTORS|ベクトルを選ばせる|整数|0|
|SF-COLOR|色を選ばせる|整数のリスト|'(0 127 255)|
|SF-TOGGLE|真偽値を選択させる (トグルのオン/オフ)|ブーリアン値|FALSE|
|SF-VALUE|数値を入力させる|数値|"10"|
|SF-STRING|文字列を入力させる|文字列|"The GIMP"|
|SF-FILENAME|ファイルを選ばせる|文字列|"/FILENAME"|
|SF-DIRNAME|ディレクトリを選ばせる|文字列|”/DIRNAME"|
|SF-ADJUSTMENT|範囲内で数値を選択させる|リスト|'(16 1 128 1 5 1)|
|SF-FONT|フォントを選ばせる|文字列|"Eras"|
|SF-PATTERN|パターンを選択させる|文字列|"Parque #1"|
|SF-BRUSH|ブラシを選択させる|リスト|'("Circle (15)" 1.0 20 0)|
|SF-GRADIENT|グラデーションを選択させる|文字列|"Blue Green"|
|SF-OPTION|リストから一つを選択させる|文字列のリスト|'("Option 1" "Option 2" "Option 3")|
|SF-PALETTE|グラデーションを選択させる|文字列|" "|
|SF-TEXT|テキストを入力させる|文字列|"Hello, GIMP"|
|SF-ENUM|Gimp が持っているエミュレーション値((gimp-2.6.6/libgimpbase/gimpbaseenums.h を参照のこと))を選ぶ|エミュ名とデフォルト値のリスト|'("InterpolationType" "linear")|
|SF-ENUM|Gimp が持っている列挙型((gimp-2.6.6/libgimpbase/gimpbaseenums.h を参照のこと))を選ぶ|列挙型名とデフォルト値のリスト|'("InterpolationType" "linear")|
|SF-DISPLAY|ディスプレイを選択させる|整数|0|

これらの中から必要な入力ボックスを作る引数型を選んで使用します。実際に自分で入力ボックスを作ってみたほうが分かりやすいでしょう。

*** 5.2.2 全ての引数型を使った例 [#vf3c1bff]

実際に上で挙げた全ての引数型を使ったスクリプトを作ってみます。そのスクリプトの実行結果がこのダイアログです。ここには全ての入力ボックスがあります。

&ref(fu5-sample-input-box.png,nolink,全ての入力ボックス);

全ての入力ボックスを持つスクリプト

※次のスクリプトを実行したとき、ダイアログで何もファイルを選択しなかった場合には script-fu.exe が落ちる不具合があります (Windows)
 (define (script-fu-all-inputs-box
                 image drawable layer channel vectors color
                 toggle value string filename dirname
                 adjustment0 adjustment1 font pattern brush
                 gradient option palette text enum display)
 
   (gimp-message "This is the input box test script!")
 )
 
 (script-fu-register
   "script-fu-all-inputs-box"
   "All Inputs Box..."
   "Show all inputs box"
   "Iccii <iccii@hotmail.com>"
   "Iccii"
   "Jun, 2001/May, 2009"
   ""
   SF-IMAGE      "SF-IMAGE"        0
   SF-DRAWABLE   "SF-DRAWABLE"     0
   SF-LAYER      "SF-LAYER"        0
   SF-CHANNEL    "SF-CHANNEL"      0
   SF-VECTORS    "SF-VECTORS"      0
   SF-COLOR      "SF-COLOR"        '(255 255 255)
   SF-TOGGLE     "SF-TOGGLE"       FALSE
   SF-VALUE      "SF-VALUE"        "10"
   SF-STRING     "SF-STRING"       "The Gimp"
   SF-FILENAME   "SF-FILENAME"     "/FILENAME"
   SF-DIRNAME    "SF-DIRNAME"      ""
   SF-ADJUSTMENT "SF-ADJUSTMENT 0" '(256 1 1024 1 10 0 0)
   SF-ADJUSTMENT "SF-ADJUSTMENT 1" '(256 1 1024 1 10 0 1)
   SF-FONT       "SF-FONT"         "Sans"
   SF-PATTERN    "SF-PATTERN"      "Leopard"
   SF-BRUSH      "SF-BRUSH"        '("Circle (15)" 1.0 20 0)
   SF-GRADIENT   "SF-GRADIENT"     "Blue Green"
   SF-OPTION     "SF-OPTION"       '("Option1" "Option2" "Option3")
   SF-PALETTE    "SF-PALETTE"      "Blues"
   SF-TEXT       "SF-TEXT"         "Try input \n any texts"
   SF-ENUM       "SF-ENUM"         '("GimpGradientType" "linear")
   SF-DISPLAY    "SF-DISPLAY"      0
 )
 
 (script-fu-menu-register "script-fu-all-inputs-box"
                          "<Image>/Filters/Test")


上の (gimp-message "This is the input box test script!") の行を下の gimp-message 出力と交換してスクリプトを実行すると、右下にあるように入力ボックスを変化させたときにどのような値を受け渡すことになるのか見ることができます。興味のある人は色々と変化させながら試してみて下さい。ブラシ名やパターン名やグラデーション名を確認したい時に便利かもしれません。

   (gimp-message (string-append 
     "Image is "      (number->string image) "\n"
     "Drawable is "   (number->string drawable) "\n"
     "Layer is "      (number->string layer) "\n"
     "Channel is "    (number->string channel) "\n"
     "Vectors is "    (number->string vectors) "\n"
     "Color is "      "'(" (number->string (car color)) " "
                           (number->string (cadr color)) " "
                           (number->string (caddr color)) ")\n"
     "Toggle is "     (if (equal? toggle TRUE) "TRUE\n" "FALSE\n")
     "Value is "      (number->string value) "\"\n"
     "String is "     "\"" string "\"\n"
     "Filename is "   "\"" filename "\"\n"
     "Dirname is "    "\"" dirname "\"\n"
     "Adjust0 is "    (number->string adjustment0) "\n"
     "Adjust1 is "    (number->string adjustment1) "\n"
     "Font is "       "\"" font "\"\n"
     "Pattern is "    "\"" pattern "\"\n"
     "Brush is "      "'(" "\"" (list-ref brush 0) "\" "
                           (number->string (list-ref brush 1)) " "
                           (number->string (list-ref brush 2)) " "
                           (number->string (list-ref brush 3)) ")\n"
     "Gradient is "   "\"" gradient "\"\n"
     "Option is "     (number->string option) "\n"
     "Palette is "    "\"" palette "\"\n"
     "Text is "       "\"" text "\"\n"
     "Enmu is "       (number->string enum) "\n"
     "Display is "    (number->string display)
   ))

実行結果がエラーメッセージとして表示されるか、エラーコンソールのダイアログに表示されます。

&ref(fu5-sample-input-box-output.png,nolink,交換した場合の出力例);

*** 5.2.3 個々の引数型の説明 [#v90b62ab]

それぞれの引数型が何を指定させるものなのかは上のダイアログを見れば大体分かると思います。この下ではそれぞれの引数型の説明と、引数型に伴うデータ型の説明をします。

''SF-IMAGE''

ドロップダウンリストからユーザーに画像を選ばせます。現在開いている画像が無い場合、none になります。選択した画像 ID が返ってきます。

>SF-IMAGE 画像 ID (整数)

画像 ID は整数です。普通は選択する画像 ID をスクリプトを書く時点で判っていることはないので 0 と仮指定((厳密には、作られた順に 0 から番号が始まるので -1 を指定したほうが良いが、仮指定なので番号をそこまで気にしなくてもいい))しておきます。

''SF-DRAWABLE''

これを書いておくと、スクリプトを実行した時点で利用できるドロアブルをユーザーに選ばせるドロップダウンリストが現れます。利用できるドロアブルが無ければ "none" とグレーアウトされ、選択できないようになります。選択したドロアブルの ID が返ってきます。

>SF-DRAWABLE ドロアブル ID (整数)

ドロアブルの ID 値を指定します。ID 値は作成された順番に Gimp によって割り当てられる、ドロアブルを識別するための整数です。ドロアブルはレイヤーとレイヤーマスクとチャンネルの総称です。通常はドロアブルの番号がスクリプトを書いた時点で判明していることは無いので、ドロアブル ID は 0 と仮指定しておきます。

''SF-LAYER''

これを書いておくと、スクリプトを実行した時点で利用できるドロアブルをユーザーに選ばせるドロップダウンリストが現れます。利用できるドロアブルが無ければ "none" とグレーアウトされ、選択できないようになります。選択したドロアブルの ID が返ってきます。

>SF-LAYER レイヤー ID (整数)

レイヤーの ID 値を指定します。ID 値は作成された順番に Gimp によって割り当てられる、レイヤーを識別するための整数です。レイヤーにレイヤーマスクがある場合、レイヤーかレイヤーマスクのアクティブになっている方が渡されます。通常はレイヤーの番号がスクリプトを書いた時点で判明していることは無いので、レイヤー ID は 0 と仮指定しておきます。

''SF-CHANNEL''

これを書いておくと、スクリプトを実行した時点で利用できるチャンネルをユーザーに選ばせるドロップダウンリストが現れます。利用できるチャンネルが無ければ "none" とグレーアウトされ、選択できないようになります。選択したチャンネルの ID が返ってきます。

>SF-CHANNEL チャンネル ID (整数)

チャンネルの ID 値を指定します。ID 値は作成された順番に Gimp によって割り当てられる、チャンネルを識別するための整数です。チャンネルには予約チャンネルを除いた残りのチャンネルが入ります。通常はチャンネルの番号がスクリプトを書いた時点で判明していることは無いので、チャンネル ID は 0 と仮指定しておきます。

''SF-VECTORS''

これを書いておくと、スクリプトを実行した時点で利用できるベクトルをユーザーに選ばせるドロップダウンリストが現れます。利用できるベクトルが無ければ "none" をグレーアウトされ、選択できないようになります。選択したベクトルの ID が返ってきます。

>SF-VECTORS ベクトル ID (整数)

ベクトルの ID を指定します。ID 値は作成された順番に Gimp によって割り当てられる、ベクトルを識別するための整数です。通常はベクトルの番号がスクリプトを書いた時点で判明していることは無いので、ベクトル ID は 0 と仮指定しておきます。

''SF-COLOR''

色ボタンを押すことでユーザーに色選択ダイアログで色を指定させます。選んだ色のリストが返ってきます。

>SF-COLOR '(赤 緑 青)
> 
>SF-COLOR "Red"

三つの数値の要素からなるリストで、赤/緑/青を表す数値をそれぞれ 0 から 255 の範囲で指定します。例えば赤色の場合は '(0 255 255) となります。または CSS 表記で色を指定することもできます。


''SF-TOGGLE''

チェックボックスを作って、ユーザに有効/無効の選択をさせます。真偽値が数値で返ってきます。0 であれば偽 (FALSE) で、それ以外は真 (TRUE) と解釈されます。

>SF-TOGGLE 真偽値 (TRUE か FALSE)

デフォルトの真偽値を、真であれば TRUE を、もしくは偽であれば FALSE で指定します。TRUE の場合はチェックボックスにチェックが入った状態となります。

''SF-VALUE''

値を入力する欄が現れます。ここに入れた値はそのままの形で直接引数に入れられます。

>SF-VALUE "値"

値であればなんでも引数に直接渡すことができます (多分配列も OK)。昔はこれで全てまかなっていたようですが、数値指定のために SF-ADJUSTMENT が新たに作られました。そのため今は SF-VALUE の出番はあまりありませんが、例えばリストを引数にしたいときには SF-VALUE を使用します。

''SF-STRING''

文字列を入力する欄が現れます。ここに数値を入力しても文字列として取り扱われます。入力した文字列が返ってきます。

>SF-STRING "文字列"

デフォルトの文字列を入れておきます。デフォルトを省略 ("") しておくこともできます。

''SF-ADJUSTMENT''

ある範囲内で数値を選ばせるアジャスターを作ります。アジャスターの種類には、スライダーとスピンボックスがあります。スピンボックスの場合は、スピンボタンを押し続けて最大値を超えた場合に最小値になります。逆も同様です。

>SF-ADJUSTMENT '(デフォルトの値 最小値 最大値 ステップ幅小 ステップ幅大 精度 アジャスターの種類)

デフォルトの値はアジャスターの初期値です。最大値と最小値は選択できる数値の範囲です。ときどき最小値を 0 にするのか 1 にするのかを考慮しなければならない場面があります。ステップ幅小はスピンボックスのスピンボタンを押したときの数値の変化量の値です。ステップ幅大はスライダーを連続して動かした時に一度に変化する量です。精度は有効な小数点位で、0 とした場合は整数を、1 とした場合は 0.1 の位を、2 とした場合は 0.01 の位を、などのように有効桁数を指定します。アジャスターの種類は、0 とするとスライダーに、1 とするとスピンボックスになります。

''SF-FONT''

ユーザにフォントを指定させます。現在のフォント名の隣のボタンを押すと、フォント選択ダイアログが開きます。ここで指定したフォントが返されます。

>SF-FONT "フォント名"

文字列でフォントを指定します。ただ単にフォント名を受け渡ししているだけなので、この時にフォントの大きさを選んでも大きさは変更されません。

''SF-PATTERN''

ユーザーにパターンを選択させます。隣のボタンを押すとパターン選択ダイアログが現れます。選択したパターンの名前が文字列で返ってきます。

>SF-PATTERN "パターン名"

パターン名は文字列です。パターン名はパターン選択ダイアログか、Script-Fu コンソールで (gimp-context-get-pattern "") を入力すると現在のパターンの情報が得られます。

''SF-BRUSH''

ユーザーにブラシを選ばせます。ブラシの名前はブラシ選択ダイアログの上部に出ている名称と必ずしも一致するわけではありません。現在のブラシの名前を調べるには (gimp-context-get-brush "") を Script-Fu コンソールに入力します。

>SF-BRUSH '("ブラシ名" 不透明度 間隔 ブラシモード)

ブラシのリストの先頭はブラシの名前 (文字列) で、残りは数値です。不透明度、間隔、ブラシモードです。

''SF-GRADIENT''

グラデーションのボタンを押すことで、グラデーション選択ダイアログでグラデーションをユーザーに選ばせます。選択したグラデーション名が返ってきます。

>SF-GRADIENT "グラデーション名"

グラデーション名はグラデーション選択ダイアログで分かります。

''SF-FILENAME''

ユーザーにファイルを指定させます。ファイル名の隣のボタンを押すとファイル選択ダイアログが開きます。ここでファイルを選択すると、ファイルまでのフルパスを含めた文字列が返されます。

>SF-FILENAME "ファイル名"

文字列でファイルの名前を指定します。パスを "/" で区切ってファイルまでのフルパスを書きます。例えば "/home/myname/picture.jpg" などです。

Script-Fu 中で参照できる環境変数 gimp-data-directory には、Gimp のデータが入っているディレクトリの場所が文字列で収められています。これを利用して、文字列を連結させる関数 string-append を使い、次のように書くこともできます。

 SF-FILENAME "Environment Map"
             (string-append "" gimp-data-directory
                            "/scripts/beavis.jpg")

''SF-DIRNAME''

ディレクトリもしくはドライブを選ぶことができます。選択していなかった場合は値を返しません。

>SF-DIRNAME "ディレクトリ名"

ディレクトリ名は文字列です。

''SF-OPTION''

ドロップダウンリストから一つをユーザーに選ばせます。先頭から何番目の要素を選んだのかという数値が返ってきます。

>SF-OPTION '("要素1" "要素2" "要素3" ... )

選ばせたいオプションの数だけ要素の文字列をリストで書きます。一番先頭の要素がデフォルトの要素になります。

''SF-PALETTE''

ユーザーにパレットを選ばせます。

>SF-PALETTE "パレット名"

パレット名は文字列です。パレット名はパレット選択ダイアログか、Script-Fu コンソールで (gimp-context-get-plaette "") を入力すると現在のパレットの名前が得られます。

''SF-TEXT''

SF-STRING は 1 行だけ入力できる文字列でしたが、SF-TEXT は複数行のテキスト文を入力することができます。

>SF-TEXT "テキスト"

テキストは文字列です。初期テキスト文に ''\n'' を入れると、そこで改行されます。

''SF-ENUM''

指定したエミュレーションタイプで選択できる値を選ぶコンボボックスが表示されます。
指定した列挙型で選択できる値を選ぶコンボボックスが表示されます。

>SF-ENUM '("エミュ名" "初期値")
>SF-ENUM '("列挙型名" "初期値")

リストの中のエミュレーション名と初期値はそれぞれ文字列です。初期値はそのエミュレーションタイプの中から初期値にしたい一つの値のニックネームを書きます。スクリプトを呼び出すと選んだエミュレーション値に対応する値が返ってきます。
リストの中の列挙型名と初期値はそれぞれ文字列です。初期値はその列挙型の中から初期値にしたい一つの値のニックネームを書きます。スクリプトを呼び出すと選んだ列挙型の対応する値が返ってきます。

''SF-DISPALY''

ディスプレイを選びます。例えば画像ウィンドウが複数ある場合は、複数のディスプレイがあることになります。

>SF-DISPLAY ディスプレイ番号

ディスプレイ番号は整数です。


** 5.3 今回のスクリプトについて [#j33d03b5]

今回作るスクリプトは、Photoshop でいうところのレイヤー効果のスクリプトです。これはレイヤーの不透明領域に対して、ドロップシャドウ、シャドウ (内側)、光彩 (外側)、光彩 (内側)、ベベルとエンボス、の効果を追加するものです。全て画像依存型スクリプトです。

今回のスクリプトは実践編ということで、Script-Fu を書く上で実際に必要になることはある程度把握したものとみなしているので、個々の部分に対してあまり長い説明はしません。もし分からないところが出てきたら、これまでの内容を復習しておいて下さい。

レイヤーの不透明部分をもとに処理を行うため、今回のスクリプトの実行前には透明なレイヤーを作成してそこに何か書き込んでおいて下さい。


** 5.4 ドロップシャドウ効果のスクリプト [#drop-shadow]

3 限目にはドロップシャドウ文字を作るスクリプトを取り上げました。ここではレイヤーの不透明部分から透明部分にドロップシャドウをするスクリプトを作ります。両者の違いについてそれぞれきちんと把握しておきましょう。

ドロップシャドウ効果は最も基本的なレイヤー効果の一つです。そのため既に Gimp 標準付属のスクリプトにはドロップシャドウのスクリプトがいくつか含まれています。それらのスクリプトと今回のスクリプトを見比べてみるのも勉強になると思います。同じことをするにもいくつかの方法があることに気が付くことでしょう。

&ref(fu5-drop-shadow.png,nolink,ドロップシャドウ);

*** 5.4.1 ドロップシャドウのスクリプト [#s2206314]

	;; ドロップシャドウを追加するスクリプト
 (define (script-fu-layer-effect-drop-shadow
                    img          ; 画像
                    layer        ; ドロアブル (レイヤー)
                    shadow-color ; 影の色
                    blur-radius  ; 影のぼかし半径
                    opacity      ; 影の不透明度
                    x-offset     ; 影の X オフセット
                    y-offset     ; 影の Y オフセット
                    )
 
   (let* (
          (width        (car (gimp-drawable-width layer)))
          (height       (car (gimp-drawable-height layer)))
          (shadow-layer (car (gimp-layer-new img width height RGBA-IMAGE
                                             "Drop Shadow" opacity MULTIPLY-MODE)))
          (shadow-mask  (car (gimp-layer-create-mask shadow-layer BLACK-MASK)))
         )
 
 	;; 処理準備
     (gimp-image-undo-group-start img)
     (gimp-context-push)
     (gimp-image-add-layer img shadow-layer -1)
     (gimp-image-add-layer-mask img shadow-layer shadow-mask)
 
 	;; シャドウレイヤーマスクの作成
     (gimp-context-set-background shadow-color)
     (gimp-drawable-fill shadow-layer BG-IMAGE-FILL)
     (gimp-selection-layer-alpha layer)
     (gimp-edit-fill shadow-mask WHITE-IMAGE-FILL)
     (gimp-selection-none img)
 
 	;; シャドウレイヤーマスクへの変更
     (gimp-context-set-background '(0 0 0))
     (gimp-channel-ops-offset shadow-mask FALSE OFFSET-BACKGROUND x-offset y-offset)
     (plug-in-gauss-iir2 1 img shadow-mask blur-radius blur-radius)
 
 	;; 後処理
     (gimp-image-lower-layer img shadow-layer)
     (gimp-context-pop)
     (gimp-image-undo-group-end img)
     (gimp-displays-flush)
   )
 )
 
 (script-fu-register
   "script-fu-layer-effect-drop-shadow"
   "Drop Shadow..."
   "Create drop shadow on the layer with alpha"
   "Iccii <iccii@hotmail.com>"
   "Iccii"
   "Aug, 2001/May, 2009"
   "RGBA"
   SF-IMAGE      "Image"               0
   SF-DRAWABLE   "Drawable"            0
   SF-COLOR      "Shadow color"        '(0 0 0)
   SF-ADJUSTMENT "Shadow blur radius"  '(10 1 100 1 10 0 0)
   SF-ADJUSTMENT "Drop shadow opacity" '(75 0 100 1 10 0 0)
   SF-ADJUSTMENT "Shadow X offset"     '(5 -100 100 1 10 0 1)
   SF-ADJUSTMENT "Shadow Y offset"     '(5 -100 100 1 10 0 1)
 )
 
 (script-fu-menu-register "script-fu-layer-effect-drop-shadow"
                          "<Image>/Filters/Layer Effect")


** 5.6 シャドウ内側効果のスクリプト [#inner-shadow]

先程は不透明部分の外側に影を落としていましたが、次は不透明部分の中に影を落とす効果です。

&ref(fu5-inner-shadow.png,nolink,シャドウ内側);

シャドウ内側のスクリプト

 	;; シャドゥ(内側) スクリプト
 (define (script-fu-layer-effect-inner-shadow
                    img          ; 画像
                    layer        ; ドロアブル (レイヤー)
                    shadow-color ; 影の色
                    blur-radius  ; 影のぼかし半径
                    opacity      ; 影の不透明度
                    x-offset     ; 影の X オフセット
                    y-offset     ; 影の Y オフセット
                    )
 
   (let* (
          (width        (car (gimp-drawable-width layer)))
          (height       (car (gimp-drawable-height layer)))
          (shadow-layer (car (gimp-layer-new img width height RGBA-IMAGE
                                             "Inner Shadow" opacity MULTIPLY-MODE)))
          (shadow-mask  (car (gimp-layer-create-mask shadow-layer WHITE-MASK)))
          (shadow-mask2 0)
         )
 
 	;; 処理準備
     (gimp-image-undo-group-start img)
     (gimp-context-push)
     (gimp-image-add-layer img shadow-layer -1)
     (gimp-image-add-layer-mask img shadow-layer shadow-mask)
 
 	;; シャドウレイヤーマスクの作成
     (gimp-context-set-background shadow-color)
     (gimp-drawable-fill shadow-layer BG-IMAGE-FILL)
     (gimp-selection-layer-alpha layer)
     (gimp-context-set-background '(0 0 0))
     (gimp-edit-fill shadow-mask BG-IMAGE-FILL)
     (gimp-selection-none img)
 
 	;; シャドウレイヤーマスクへの変更
     (gimp-context-set-background '(0 0 0))
     (gimp-channel-ops-offset shadow-mask FALSE OFFSET-BACKGROUND x-offset y-offset)
     (plug-in-gauss-iir2 1 img shadow-mask blur-radius blur-radius)
 
 	;; もう一度レイヤーマスクを作る
     (gimp-image-remove-layer-mask img shadow-layer APPLY)
     (set! shadow-mask2 (car (gimp-layer-create-mask shadow-layer BLACK-MASK)))
     (gimp-image-add-layer-mask img shadow-layer shadow-mask2)
     (gimp-selection-layer-alpha layer)
     (gimp-edit-fill shadow-mask2 WHITE-IMAGE-FILL)
     (gimp-selection-none img)
 
 	;; 後処理
     (gimp-context-pop)
     (gimp-image-undo-group-end img)
     (gimp-displays-flush)
   )
 )
 
 (script-fu-register
   "script-fu-layer-effect-inner-shadow"
   "Inner Shadow..."
   "Create inner shadow on the layer with alpha"
   "Iccii <iccii@hotmail.com>"
   "Iccii"
   "Aug, 2001/May, 2009"
   "RGBA"
   SF-IMAGE      "Image"               0
   SF-DRAWABLE   "Drawable"            0
   SF-COLOR      "Shadow color"        '(0 0 0)
   SF-ADJUSTMENT "Shadow blur radius"  '(10 1 100 1 10 0 0)
   SF-ADJUSTMENT "Drop shadow opacity" '(75 0 100 1 10 0 0)
   SF-ADJUSTMENT "Shadow X offset"     '(5 -100 100 1 10 0 1)
   SF-ADJUSTMENT "Shadow Y offset"     '(5 -100 100 1 10 0 1)
 )
 
 (script-fu-menu-register "script-fu-layer-effect-inner-shadow"
                          "<Image>/Filters/Layer Effect")



** 5.7 レイヤー光彩外側効果のスクリプト [#outer-glow]

不透明部分がまるで外側に向かって発光しているかのような効果のスクリプトです。

&ref(fu5-outer-glow.png,nolink,レイヤー光彩外側);

レイヤー光彩外側のスクリプト

	;; レイヤー光彩 (外側) スクリプト
 (define (script-fu-layer-effect-outer-glow
                    img          ; 画像
                    layer        ; ドロアブル (レイヤー)
                    glow-color   ; 光彩の色
                    blur-radius  ; 光彩のぼかし半径
                    glow-radius  ; 光彩の半径
                    opacity      ; 光彩の不透明度
                    )
 
   (let* (
          (width      (car (gimp-drawable-width layer)))
          (height     (car (gimp-drawable-height layer)))
          (glow-layer (car (gimp-layer-new img width height RGBA-IMAGE
                                           "Outer Glow" opacity SCREEN-MODE)))
          (glow-mask  (car (gimp-layer-create-mask glow-layer BLACK-MASK)))
         )
 
 	;; 処理準備
     (gimp-image-undo-group-start img)
     (gimp-context-push)
     (gimp-image-add-layer img glow-layer -1)
     (gimp-image-add-layer-mask img glow-layer glow-mask)
 
 	;; 光彩レイヤーマスクの作成
     (gimp-context-set-background glow-color)
     (gimp-drawable-fill glow-layer BG-IMAGE-FILL)
     (gimp-selection-layer-alpha layer)
     (gimp-selection-grow img glow-radius)
     (gimp-edit-fill glow-mask WHITE-IMAGE-FILL)
     (gimp-selection-none img)
 
 	;; 光彩レイヤーマスクへの変更
     (gimp-context-set-background '(0 0 0))
     (plug-in-gauss-iir2 1 img glow-mask blur-radius blur-radius)
 
 	;; 後処理
     (gimp-image-lower-layer img glow-layer)
     (gimp-context-pop)
     (gimp-image-undo-group-end img)
     (gimp-displays-flush)
   )
 )
 
 (script-fu-register
   "script-fu-layer-effect-outer-glow"
   "Outer Glow..."
   "Create outer glow on the layer with alpha"
   "Iccii <iccii@hotmail.com>"
   "Iccii"
   "Aug, 2001/May, 2009"
   "RGBA"
   SF-IMAGE      "Image"               0
   SF-DRAWABLE   "Drawable"            0
   SF-COLOR      "Glow color"          '(255 255 191)
   SF-ADJUSTMENT "Blur radius"         '(10 1 100 1 10 0 0)
   SF-ADJUSTMENT "Glow radius"         '(2 1 100 1 10 0 0)
   SF-ADJUSTMENT "Opacity"             '(75 0 100 1 10 0 0)
 )
 
 (script-fu-menu-register "script-fu-layer-effect-outer-glow"
                          "<Image>/Filters/Layer Effect")



** 5.8 レイヤー光彩内側効果のスクリプト [#inner-glow]

外側から不透明部分の中に向かって発光しているかのような効果のスクリプトです。光彩のタイプとして、不透明部分の縁が光るのか内部が光るのかを選ぶことができます。

&ref(fu5-inner-glow.png,nolink,レイヤー光彩内側);

レイヤー光彩内側のスクリプト

 	;; レイヤー光彩 (内側) スクリプト
 (define (script-fu-layer-effect-inner-glow
                    img          ; 画像
                    layer        ; ドロアブル (レイヤー)
                    glow-color   ; 光彩の色
                    blur-radius  ; 光彩のぼかし半径
                    glow-radius  ; 光彩の半径
                    opacity      ; 光彩の不透明度
                    glow-type    ; 光彩のタイプ (縁 or 内部)
                    )
 
   (let* (
          (width      (car (gimp-drawable-width layer)))
          (height     (car (gimp-drawable-height layer)))
          (glow-layer (car (gimp-layer-new img width height RGBA-IMAGE
                                           "Inner Glow" opacity SCREEN-MODE)))
          (glow-mask  (car (gimp-layer-create-mask glow-layer WHITE-MASK)))
          (glow-mask2 0)
         )
 
 	;; 処理準備
     (gimp-image-undo-group-start img)
     (gimp-context-push)
     (gimp-image-add-layer img glow-layer -1)
     (gimp-image-add-layer-mask img glow-layer glow-mask)
 
 	;; 光彩レイヤーマスクの作成
     (gimp-context-set-background glow-color)
     (gimp-drawable-fill glow-layer BG-IMAGE-FILL)
     (gimp-selection-layer-alpha layer)
     (gimp-selection-invert img)
     (gimp-selection-grow img glow-radius)
     (gimp-selection-invert img)
     (gimp-context-set-background '(0 0 0))
     (gimp-edit-fill glow-mask BG-IMAGE-FILL)
     (gimp-selection-none img)
 
 	;; 光彩レイヤーマスクへの変更
     (plug-in-gauss-iir2 1 img glow-mask blur-radius blur-radius)
     (if (eqv? glow-type 1)
         (gimp-invert glow-mask))
 
 	;; もう一度レイヤーマスクを作る
     (gimp-image-remove-layer-mask img glow-layer APPLY)
     (set! glow-mask2 (car (gimp-layer-create-mask glow-layer BLACK-MASK)))
     (gimp-image-add-layer-mask img glow-layer glow-mask2)
     (gimp-selection-layer-alpha layer)
     (gimp-edit-fill glow-mask2 WHITE-IMAGE-FILL)
     (gimp-selection-none img)
 
 	;; 後処理
     (gimp-context-pop)
     (gimp-image-undo-group-end img)
     (gimp-displays-flush)
   )
 )
 
 (script-fu-register
   "script-fu-layer-effect-inner-glow"
   "Inside Glow..."
   "Create inner glow on the layer with alpha"
   "Iccii <iccii@hotmail.com>"
   "Iccii"
   "Aug, 2001/May, 2009"
   "RGBA"
   SF-IMAGE      "Image"               0
   SF-DRAWABLE   "Drawable"            0
   SF-COLOR      "Glow color"          '(255 255 191)
   SF-ADJUSTMENT "Blur radius"         '(10 1 100 1 10 0 0)
   SF-ADJUSTMENT "Glow radius"         '(2 1 100 1 10 0 0)
   SF-ADJUSTMENT "Opacity"             '(75 0 100 1 10 0 0)
   SF-OPTION     "Glow type"           '("Edge" "Inner")
 )
 
 (script-fu-menu-register "script-fu-layer-effect-inner-glow"
                          "<Image>/Filters/Layer Effect")


** 5.9 スクリプトの発展 [#b894f13a]

今回の四つのスクリプトを入力した人は多分、それぞれのスクリプトがほとんど同じような手順になっていることに気が付くでしょう。実際、これらの効果は非常に良く似た手順で行うことができます。

スクリプトの中から共通する部分を抜き出して、それを一つの関数として書き、共通関数をそれぞれの効果のスクリプトから呼び出すことでそれぞれの効果が行えるようになればスクリプトが簡潔になります。

共通関数を呼び出す時には、それぞれのスクリプトの固有の処理を共通関数に何らかの方法で教えてやる必要があります。この辺を工夫しなければなりません。


** 5.10 さらなる学習のために [#t0b1ae86]

スクリプトを書くための基本知識を得て最初にいくつかスクリプトを書いた後は、さらに複雑な処理を行うスクリプトを自分で書きたくなることでしょう。
そのためにできる一番の近道は、すでにあるスクリプトを改造したりしてどんどん試すことです。例えば GIMP には basic1-logo.scm という基本的なロゴのスクリプトが入っています。基本的なログゆえに、スクリプトの作り方などを参考にするには最高の素材となることでしょう。

basic1-logo.scm の構造は次のようになっています。

:apply-basic1-logo-effect|logo-layer に対して basic1-logo の効果を適用する関数です。ここには実際の効果を適用するための処理が書かれています。
:script-fu-basic1-logo-alpha|ここでは apply-basic1-logo-effect を呼び出すことで、透明度に基づいて basic1-logo の効果を適用させています。いわゆる、''フィルタ→ロゴ効果'' に該当します。
:script-fu-basic1-logo|ここでは、まず画像を作成して透明レイヤー上にテキストを設置しています。これに対して apply-basic1-logo-effect を呼び出すことで、不透明部分 (つまりロゴの部分) に basic1-logo の効果を適用させています。いわゆる、''ファイル→新しい画像の作成→ロゴ'' に該当します。

また、次の関数がスクリプト中から呼び出されます。

:script-fu-util-image-resize-from-layer|script-fu-util.scm にて定義されている関数で、apply-basic1-logo-effect 関数内で定義されています。レイヤーのサイズをベースに、画像のサイズをレイヤーと同一のサイズに変更するというものです。用途は主に script-fu-basic1-logo にて存在する画像の大きさとロゴレイヤーの大きさがことなるので、それを合わせるということです。

script-fu-basic1-logo は独立実行型スクリプトであり、script-fu-basic1-logo-alpha は画像依存型スクリプトです。そしてその両方から呼び出される apply-basic1-logo-effect が実際の効果適用の処理部分という構造になっています。

最初から処理を分けた構造のスクリプトを書くことは難しいでしょうが、将来的にはこのような発展も視野に入れておくと良いでしょう。

-----

CENTER:[[四限目>ScriptFuClass/Step4]] | [[Script-Fu 青空教室>ScriptFuClass]] | [[放課後>ScriptFuClass/After]]

Backup   RSS of recent changes