トップ > Script-Fuスクリプトの制作 >
簡単なスクリプトを作成してみよう

  

少しだけ役に立つスクリプトを作成することでコツをつかむ

ここまでは、プログラミング言語SchemeおよびScript-Fuプログラミングの基礎的な知識について解説してきました。

この記事では、ほんの少しだけ役に立つスクリプトを作成してみます。 範囲選択されている領域を指定された色で塗りつぶすスクリプトです。

範囲選択されている領域を指定された色で塗りつぶす

では、範囲選択されている領域を指定された色で塗りつぶすスクリプトを作成していきましょう。 なお、最初から高機能なものは目指しません。 最初は必要最低限の機能しか持たないスクリプトを作成し、徐々に肉付けしていきます

まずは、必要最低限の機能でスクリプトを作成しましょう。 スクリプトファイル myscript.scm を以下のように書き換えます。

  1. (define (myscript image color)
  2. (if (= (car (gimp-selection-is-empty image)) TRUE)
  3. (begin
  4. (gimp-message "範囲選択されていません。")
  5. )
  6. (begin
  7. (gimp-context-set-foreground color)

  8. (gimp-drawable-edit-fill (car (gimp-image-get-active-layer image)) FOREGROUND-FILL)

  9. (gimp-selection-none image)

  10. (gimp-displays-flush)
  11. )
  12. )
  13. )

  14. (script-fu-register
  15. "myscript" ; 登録する関数の名前
  16. "My Script" ; メニュー項目のラベル
  17. "自作の練習用スクリプトです" ; メニュー項目の説明
  18. "My Name" ; 作成者の名前
  19. "My Name" ; 著作権者の名前
  20. "January 1, 2023" ; 作成日(改訂日)
  21. "RGB* GRAY*" ; メニュー項目を有効にするための条件
  22. SF-IMAGE "Image" 0 ; 画像番号
  23. SF-COLOR "Color" '(255 0 0) ; 色
  24. )

  25. (script-fu-menu-register
  26. "myscript" ; 対象の関数の名前
  27. "<Image>/Filters" ; メニュー項目の位置
  28. )
 

それでは、今回のスクリプトを詳しく見ていきましょう。 まず目を引くのが27行目の、

SF-COLOR    "Color" '(255 0 0)      ; 色

の部分です。 新たな引数の型の SF-COLOR が登場しています。 名前から予想できるように色を受け渡すための型です。

スクリプトへの引数の型 意味
SF-COLOR 色を受け渡す
※入力ダイアログが開く

なお、SF-COLOR に続く引数の "Color" は、いつものように入力ダイアログでのラベルです。

さらに続く '(255 0 0) は、色の初期値を赤・緑・青成分のリストで表現したものです。 つまり、今回の例では色の初期値に赤色を設定しています。

次に注目すべきは2行目の、

(if (= (car (gimp-selection-is-empty image)) TRUE)

という記述です。 この行は、手続き gimp-selection-is-emptyの戻り値が TRUE かどうかを判定しています。

手続き gimp-selection-is-emptyは範囲選択されていなければ TRUE を返します。

手続き 機能
gimp-selection-is-empty 範囲選択されていない状態かを返す
※範囲選択されていない状態ならTRUEを返す

範囲選択されていなければ4行目の、

(gimp-message "範囲選択されていません。")

が実行されてメッセージが表示されます。 範囲選択されていれば7行目から13行目の、

(gimp-context-set-foreground color)

(gimp-drawable-edit-fill (car (gimp-image-get-active-layer image)) FOREGROUND-FILL)

(gimp-selection-none image)

(gimp-displays-flush)

が実行さます。 それぞれの手続きの機能は以下の通りです。

手続き 機能
gimp-context-set-foreground 描画色を設定する
gimp-drawable-edit-fill 範囲選択されている領域を塗りつぶす
gimp-selection-none 範囲選択を解除する
gimp-displays-flush 変更内容を表示に反映する

つまり、範囲選択されている領域を利用者が入力ダイアログで指定した色で塗りつぶし、さらに範囲選択を解除する、という処理です。


では、作成したスクリプトを実行してみましょう。 このスクリプトは画像を開いた状態でしか実行できませんので、何か画像を開いてください。

1. 任意の画像を開く
1. 任意の画像を開く

上図のように任意の画像を開きます。 今回は新規画像を作成しました。

最初は、範囲選択していない状態でスクリプトを実行しましょう。 プルダウンメニューの"フィルター(R) -> My Script"を実行します。

2. 入力ダイアログが表示される
2. 入力ダイアログが表示される

上図のように入力ダイアログが表示されます。 色を指定するための入力欄 "Color" が表示され、初期値が赤色になっています。

では、このまま何もせずに[OK(O)]ボタンを押してください。

3. メッセージダイアログに "範囲選択されていません。" と表示される
3. メッセージダイアログに "範囲選択されていません。" と表示される

上図のようにメッセージダイアログに "範囲選択されていません。" と表示されます。 範囲選択していなかったため、警告が表示されました。

では、今度は範囲選択してからスクリプトを実行してみましょう

4. 画像の一部を範囲選択する
4. 画像の一部を範囲選択する

上図のように画像の一部を範囲選択します。

では、もう一度スクリプトを実行しましょう。 プルダウンメニューの"フィルター(R) -> My Script"を実行します。

5. 入力ダイアログが表示される
5. 入力ダイアログが表示される

上図のように入力ダイアログで任意の色を指定します。 今回の例では青色を指定しています。

色を指定したら[OK(O)]ボタンを押してください。

6. 範囲選択されている領域が指定された色で塗りつぶされる
6. 範囲選択されている領域が指定された色で塗りつぶされる

上図のように範囲選択されていた領域が指定された色で塗りつぶされます。 また、範囲選択が解除されていることがわかります。

ただし、まだまだ改善が必要です。 また、いくつかの問題があります

では、問題点や要改善点を見ていきましょう。

7. ツールボックスの前景色が変化している
7. ツールボックスの前景色が変化している

上図のようにツールボックスの前景色が入力ダイアログで指定された色に変化しています。 これは、手続き gimp-context-set-foregroundによる結果ですが、利用者にしてみれば迷惑な話です。 スクリプト実行後も、前景色や背景色は元のままであるべきです

続いての問題点は、実はまだ見えていません。 今はまだ問題点は隠れているのです。 問題を表に出すには、編集を取り消す必要があります。 キーボードのCTRL+Zを押してください。

8. 範囲選択は戻るが塗りつぶしは取り消されない
8. 範囲選択は戻るが塗りつぶしは取り消されない

上図のように解除されていた範囲選択が戻りました。 ただし、塗りつぶしは取り消されていません

ではここで、再度キーボードのCTRL+Zを押してください。

9. 塗りつぶしも取り消される
9. 塗りつぶしも取り消される

上図のように塗りつぶしも取り消されます。 このように、スクリプト実行前の状態に戻すのに2回の取り消し操作が必要です。 手続き gimp-drawable-edit-fillと手続き gimp-selection-noneの結果がそれぞれ別々に取り消されるためです。

これでは不便ですので、1回のCTRL+Zの操作でスクリプトの実行前まで戻せるようにしましょう

続いては、問題点というよりは要改善点です。

10. 既存のレイヤ上で塗りつぶしが行われている
10. 既存のレイヤ上で塗りつぶしが行われている

上図のように既存のレイヤ上で塗りつぶしが行われています。 これだと元の画像が失われることになります

これを改善し、新たにレイヤを作成し、そのレイヤを塗りつぶすように変更しましょう。

前景色が変化しないようにする

まずは、ツールボックスの前景色が変化する問題を解決しましょう。 スクリプトファイル myscript.scm を以下のように修正してください。

  1. (define (myscript image color)
  2. (if (= (car (gimp-selection-is-empty image)) TRUE)
  3. (begin
  4. (gimp-message "範囲選択されていません。")
  5. )
  6. (begin
  7. (gimp-context-push)

  8. (gimp-context-set-foreground color)

  9. (gimp-drawable-edit-fill (car (gimp-image-get-active-layer image)) FOREGROUND-FILL)

  10. (gimp-selection-none image)

  11. (gimp-displays-flush)

  12. (gimp-context-pop)
  13. )
  14. )
  15. )

  16. (script-fu-register
  17. "myscript" ; 登録する関数の名前
  18. "My Script" ; メニュー項目のラベル
  19. "自作の練習用スクリプトです" ; メニュー項目の説明
  20. "My Name" ; 作成者の名前
  21. "My Name" ; 著作権者の名前
  22. "January 1, 2023" ; 作成日(改訂日)
  23. "RGB* GRAY*" ; メニュー項目を有効にするための条件
  24. SF-IMAGE "Image" 0 ; 画像番号
  25. SF-COLOR "Color" '(255 0 0) ; 色
  26. )

  27. (script-fu-menu-register
  28. "myscript" ; 対象の関数の名前
  29. "<Image>/Filters" ; メニュー項目の位置
  30. )
 

修正箇所は7行目の、

(gimp-context-push)

と、17行目の、

(gimp-context-pop)

です。 どちらも新たに追加された行です。 どちらの行にも、今まで紹介していない手続きが登場しています。

それぞれの手続きの機能は以下の通りです。

手続き 機能
gimp-context-push コンテキスト(描画設定情報)を保存する
※スタックの一番上に積む
gimp-context-pop コンテキスト(描画設定情報)を取り出す
※スタックの一番上から取り出す

コンテキストとは描画設定情報のことで、前景色・背景色・ブラシサイズ・ブラシ形状などを "ひとまとめ" にした情報のことです。

なお、手続き gimp-context-pushは、コンテキストを "スタック" と呼ばれる場所に積み上げます。 スタックは情報を積み重ねることができる箱のようなものです。 紙に描画設定情報を書きとめ、それを箱に入れるところを想像してください。 箱の中には紙が1枚増えます。

それに対して、手続き gimp-context-popは、スタックの一番上に積まれた情報を取り出してコンテキストに戻します。 箱の中の一番上にある紙を取り出し、描画設定情報に戻すところを想像してください。 箱の中からは紙が1枚減ります。


修正してもまだスクリプトは実行しないでください。 最後にまとめて確認します。

  
実行しても問題ありません。 今すぐ結果を知りたい方はぜひ実行してみてください。

1回の取り消し操作でスクリプト実行前まで戻す

続いては、『スクリプト実行前の状態に戻すのに2回の取り消し操作が必要』という問題を解決しましょう。

1回の取り消し操作でスクリプト実行前まで戻るように修正します。 スクリプトファイル myscript.scm を以下のように修正してください。

  1. (define (myscript image color)
  2. (if (= (car (gimp-selection-is-empty image)) TRUE)
  3. (begin
  4. (gimp-message "範囲選択されていません。")
  5. )
  6. (begin
  7. (gimp-context-push)

  8. (gimp-image-undo-group-start image)

  9. (gimp-context-set-foreground color)

  10. (gimp-drawable-edit-fill (car (gimp-image-get-active-layer image)) FOREGROUND-FILL)

  11. (gimp-selection-none image)

  12. (gimp-displays-flush)

  13. (gimp-image-undo-group-end image)

  14. (gimp-context-pop)
  15. )
  16. )
  17. )

  18. (script-fu-register
  19. "myscript" ; 登録する関数の名前
  20. "My Script" ; メニュー項目のラベル
  21. "自作の練習用スクリプトです" ; メニュー項目の説明
  22. "My Name" ; 作成者の名前
  23. "My Name" ; 著作権者の名前
  24. "January 1, 2023" ; 作成日(改訂日)
  25. "RGB* GRAY*" ; メニュー項目を有効にするための条件
  26. SF-IMAGE "Image" 0 ; 画像番号
  27. SF-COLOR "Color" '(255 0 0) ; 色
  28. )

  29. (script-fu-menu-register
  30. "myscript" ; 対象の関数の名前
  31. "<Image>/Filters" ; メニュー項目の位置
  32. )
 

修正箇所は9行目の、

(gimp-image-undo-group-start image)

と、19行目の、

(gimp-image-undo-group-end image)

です。 どちらも新たに追加された行です。 どちらの行にも、新たな手続きが登場しています。

これらの手続きの機能は以下の通りです。

手続き 機能
gimp-image-undo-group-start 編集の取り消しのグループ化を開始する
gimp-image-undo-group-end 編集の取り消しのグループ化を終了する

簡単に言えば、手続き gimp-image-undo-group-start と gimp-image-undo-group-end で囲まれている部分が1つの変更とみなされる、ということです。


修正してもまだスクリプトは実行しないでください。 最後にまとめて確認します。

  
実行しても問題ありません。 今すぐ結果を知りたい方はぜひ実行してみてください。

選択中のレイヤではなく新たなレイヤを追加してそこを塗りつぶす

続いて修正するのは、『既存のレイヤ上で塗りつぶしが行われているため元の情報が失われてしまう』という問題です。

これを改善し、新たにレイヤを作成し、そのレイヤを塗りつぶすように変更します。 スクリプトファイル myscript.scm を以下のように書き換えます。

  1. (define (myscript image color)
  2. (let
  3. (
  4. (activelayer-id 0)

  5. (filllayer-id 0)
  6. (filllayer-width 0)
  7. (filllayer-height 0)
  8. )

  9. (if (= (car (gimp-selection-is-empty image)) TRUE)
  10. (begin
  11. (gimp-message "範囲選択されていません。")
  12. )
  13. (begin
  14. (gimp-context-push)

  15. (gimp-image-undo-group-start image)

  16. (set! activelayer-id (car (gimp-image-get-active-layer image)))

  17. (set! filllayer-width (car (gimp-image-width image)))
  18. (set! filllayer-height (car (gimp-image-height image)))

  19. (set! filllayer-id (car (gimp-layer-new image filllayer-width filllayer-height 1 "塗りつぶし" 100 0)))

  20. (gimp-image-add-layer image filllayer-id -1)

  21. (gimp-image-set-active-layer image filllayer-id)

  22. (gimp-context-set-foreground color)

  23. (gimp-drawable-edit-fill (car (gimp-image-get-active-layer image)) FOREGROUND-FILL)

  24. (gimp-selection-none image)

  25. (gimp-image-set-active-layer image activelayer-id)

  26. (gimp-displays-flush)

  27. (gimp-image-undo-group-end image)

  28. (gimp-context-pop)
  29. )
  30. )
  31. )
  32. )

  33. (script-fu-register
  34. "myscript" ; 登録する関数の名前
  35. "My Script" ; メニュー項目のラベル
  36. "自作の練習用スクリプトです" ; メニュー項目の説明
  37. "My Name" ; 作成者の名前
  38. "My Name" ; 著作権者の名前
  39. "January 1, 2023" ; 作成日(改訂日)
  40. "RGB* GRAY*" ; メニュー項目を有効にするための条件
  41. SF-IMAGE "Image" 0 ; 画像番号
  42. SF-COLOR "Color" '(255 0 0) ; 色
  43. )

  44. (script-fu-menu-register
  45. "myscript" ; 対象の関数の名前
  46. "<Image>/Filters" ; メニュー項目の位置
  47. )
 

変更後のスクリプトでまず目につくのが、4行目から8行目の、

(activelayer-id   0)

(filllayer-id     0)
(filllayer-width  0)
(filllayer-height 0)

という、変数の宣言の部分です。 これらの変数の役割は以下です。

変数 役割
activelayer-id 選択中のレイヤのレイヤ番号
※レイヤの選択状態をスクリプト実行前に戻すために使う
filllayer-id 塗りつぶし用レイヤのレイヤ番号
filllayer-width 塗りつぶし用レイヤの幅
filllayer-height 塗りつぶし用レイヤの高さ

続いて注目すべき行が、20行目と37行目の、

(set! activelayer-id (car (gimp-image-get-active-layer image)))
(gimp-image-set-active-layer image activelayer-id)

という2つの行です。 これらの手続きの機能は以下の通りです。

手続き 機能
gimp-image-get-active-layer 選択中のレイヤのレイヤ番号を返す
gimp-image-set-active-layer 指定されたレイヤを選択状態にする

つまり、スクリプト実行前と実行後でレイヤの選択状態が変化しないようにするための処理です。

22行目から29行目の、

(set! filllayer-width (car (gimp-image-width image)))
(set! filllayer-height (car (gimp-image-height image)))

(set! filllayer-id (car (gimp-layer-new image filllayer-width filllayer-height 1 "塗りつぶし" 100 0)))

(gimp-image-add-layer image filllayer-id -1)

(gimp-image-set-active-layer image filllayer-id)

が、新たにレイヤを作成している部分です。 初登場の新たな手続きも含めて、いくつかの手続きが利用されています。

これらの手続きの機能は以下の通りです。

手続き 機能
gimp-image-width 画像の幅を返す
※ キャンバスの幅のこと
gimp-image-height 画像の高さを返す
※ キャンバスの高さのこと
gimp-layer-new 新たなレイヤを作成しレイヤ番号を返す
※画像とはまだ結びつかない
gimp-image-add-layer 指定されたレイヤを画像に追加する
※画像とレイヤが結びつく
gimp-image-set-active-layer 指定されたレイヤを選択状態にする

やっていることは、

  1. キャンバスの幅と高さを取得する
  2. キャンバスサイズと同じ大きさのレイヤを "塗りつぶし" という名前で作成する
  3. 作成したレイヤを画像に追加する
  4. 作成したレイヤを選択状態にする

ということです。

31行目から35行目の、

(gimp-context-set-foreground color)

(gimp-drawable-edit-fill (car (gimp-image-get-active-layer image)) FOREGROUND-FILL)

(gimp-selection-none image)

は、今までと変わらずで、範囲選択されている領域を指定された色で塗りつぶす、という処理です。


では、スクリプトを実行してみましょう。 このスクリプトは画像を開いた状態でしか実行できませんので、何か画像を開いてください。

1. 任意の画像を開く
1. 任意の画像を開く

上図のように任意の画像を開きます。 今回は新規画像を作成しました。

2. 画像の一部を範囲選択する
2. 画像の一部を範囲選択する

上図のように画像の一部を範囲選択します。

それでは、スクリプトを実行しましょう。 プルダウンメニューの"フィルター(R) -> My Script"を実行します。

3. 入力ダイアログが表示される
3. 入力ダイアログが表示される

上図のように入力ダイアログが表示されるのでColorに任意の色を指定します。 今回の例では緑色を指定しています。

色を指定したら[OK(O)]ボタンを押してください。

4. 範囲選択されている領域が指定された色で塗りつぶされる
4. 範囲選択されている領域が指定された色で塗りつぶされる

上図のように範囲選択されていた領域が指定された色で塗りつぶされます。 また、範囲選択が解除されています。

ではここで、レイヤーダイアログにあるレイヤ一覧に注目してください。

5. "塗りつぶし" という名称のレイヤが作成されている
5. "塗りつぶし" という名称のレイヤが作成されている

上図のように "塗りつぶし" という名称のレイヤが作成されています。 レイヤ一覧の縮小画像を見ればわかるように、塗りつぶされているのはこのレイヤです。

では、ツールボックスの前景色も見ておきましょう。

6. ツールボックスの前景色は実行前のまま
6. ツールボックスの前景色は実行前のまま

上図のようにツールボックスの前景色はスクリプト実行前のままです。 ツールボックスの前景色が変化する、という問題は解決されています。

では、編集を取り消しも行ってみましょう。 キーボードのCTRL+Zを押してください。

7. 範囲選択は戻るが塗りつぶしは取り消されない
7. 範囲選択は戻るが塗りつぶしは取り消されない

上図のように1回の取り消し操作でスクリプト実行前の状態に戻りました。 1回の取り消し操作でスクリプト実行前まで戻らない、という問題も解決できています。

最初に比べると、随分と使い勝手のよいスクリプトになりました。 ただし、まだ改善が必要な点があります

では、要改善点を見ていきましょう。 要改善点とは、『スクリプトを実行するたびに "塗りつぶし" という名称のレイヤが作られる』、という問題点です。 実際にやってみましょう。

8. 画像の一部を範囲選択する
8. 画像の一部を範囲選択する

上図のように画像の一部を範囲選択します。

それでは、スクリプトを実行しましょう。 プルダウンメニューの"フィルター(R) -> My Script"を実行します。

9. 入力ダイアログが表示される
9. 入力ダイアログが表示される

上図のように入力ダイアログが表示されるのでColorに任意の色を指定します。 今回の例では黒色を指定しています。

色を指定したら[OK(O)]ボタンを押してください。

10. 範囲選択されている領域が指定された色で塗りつぶされる
10. 範囲選択されている領域が指定された色で塗りつぶされる

上図のように範囲選択されていた領域が指定された色で塗りつぶされます。 また、範囲選択が解除されています。 ここまでは問題ありません。

ではここで、塗りつぶしをさらに実行してみましょう

11. 画像の一部を範囲選択する
11. 画像の一部を範囲選択する

上図のように再度画像の一部を範囲選択します。 1回目とは違う場所・違う形で範囲選択する方が見やすくていいでしょう。

では、スクリプトを再度実行しましょう。 プルダウンメニューの"フィルター(R) -> My Script"を実行します。

12. 入力ダイアログが表示される
12. 入力ダイアログが表示される

上図のように入力ダイアログが表示されるのでColorに任意の色を指定します。 今回の例では水色を指定しています。

色を指定したら[OK(O)]ボタンを押します。

13. 範囲選択されている領域が指定された色で塗りつぶされる
13. 範囲選択されている領域が指定された色で塗りつぶされる

上図のように範囲選択されていた領域が指定された色で塗りつぶされます。 また、範囲選択が解除されています。 一見、問題なさそうに見えます。

ではここで、レイヤーダイアログにあるレイヤ一覧に注目してください。

14. "塗りつぶし #1" という名称のレイヤも作成されている
14. "塗りつぶし #1" という名称のレイヤも作成されている

上図のように "塗りつぶし" という名称のレイヤの他に "塗りつぶし #1" という名称のレイヤが作成されています。

スクリプトの2回目の実行時には、"塗りつぶし" という名称のレイヤはすでに存在しています。 そのため、レイヤ名称の重複を防ぐためにGIMPが自動的に "#1" を足してしまったのです

スクリプトを実行するたびに "塗りつぶし" という名称のレイヤを作ろうとしていることが根本的な問題です

レイヤ名称の重複を防ぐように改善する

では、最後の改善を行いましょう。 無条件に "塗りつぶし" という名称のレイヤを作るのを止め、すでに "塗りつぶし" というレイヤがある場合はそのレイヤを塗りつぶすようにします。

"塗りつぶし" レイヤがある → そのレイヤを塗りつぶす
"塗りつぶし" レイヤはない → "塗りつぶし" レイヤを作成して塗りつぶす

では、スクリプトを改善しましょう。 スクリプトファイル myscript.scm を以下のように修正します。

  1. (define (myscript image color)
  2. (let
  3. (
  4. (activelayer-id 0)

  5. (filllayer-id 0)
  6. (filllayer-width 0)
  7. (filllayer-height 0)
  8. )

  9. (if (= (car (gimp-selection-is-empty image)) TRUE)
  10. (begin
  11. (gimp-message "範囲選択されていません。")
  12. )
  13. (begin
  14. (gimp-context-push)

  15. (gimp-image-undo-group-start image)

  16. (set! activelayer-id (car (gimp-image-get-active-layer image)))

  17. (set! filllayer-width (car (gimp-image-width image)))
  18. (set! filllayer-height (car (gimp-image-height image)))

  19. (set! filllayer-id (car (gimp-image-get-layer-by-name image "塗りつぶし")))

  20. (if (= filllayer-id -1)
  21. (begin
  22. (set! filllayer-id (car (gimp-layer-new image filllayer-width filllayer-height 1 "塗りつぶし" 100 0)))

  23. (gimp-image-add-layer image filllayer-id -1)
  24. )
  25. )

  26. (gimp-image-set-active-layer image filllayer-id)

  27. (gimp-context-set-foreground color)

  28. (gimp-drawable-edit-fill (car (gimp-image-get-active-layer image)) FOREGROUND-FILL)

  29. (gimp-selection-none image)

  30. (gimp-image-set-active-layer image activelayer-id)

  31. (gimp-displays-flush)

  32. (gimp-image-undo-group-end image)

  33. (gimp-context-pop)
  34. )
  35. )
  36. )
  37. )

  38. (script-fu-register
  39. "myscript" ; 登録する関数の名前
  40. "My Script" ; メニュー項目のラベル
  41. "自作の練習用スクリプトです" ; メニュー項目の説明
  42. "My Name" ; 作成者の名前
  43. "My Name" ; 著作権者の名前
  44. "January 1, 2023" ; 作成日(改訂日)
  45. "RGB* GRAY*" ; メニュー項目を有効にするための条件
  46. SF-IMAGE "Image" 0 ; 画像番号
  47. SF-COLOR "Color" '(255 0 0) ; 色
  48. )

  49. (script-fu-menu-register
  50. "myscript" ; 対象の関数の名前
  51. "<Image>/Filters" ; メニュー項目の位置
  52. )
 

修正したのは25行目から33行目の、

(set! filllayer-id (car (gimp-image-get-layer-by-name image "塗りつぶし")))

(if (= filllayer-id -1)
    (begin
        (set! filllayer-id (car (gimp-layer-new image filllayer-width filllayer-height 1 "塗りつぶし" 100 0)))

        (gimp-image-add-layer image filllayer-id -1)
    )
)

の部分です。 新たな手続き gimp-image-get-layer-by-name が登場していますが、この手続きの機能は以下の通りです。

手続き 機能
gimp-image-get-layer-by-name 指定された名称のレイヤのレイヤ番号を返す
※見つからない場合は -1 を返す

つまり、この部分でやっていることは、

  1. "塗りつぶし" という名称のレイヤを探す
  2. レイヤが存在いなければ "塗りつぶし" という名称のレイヤを追加する
  3. "塗りつぶし" という名称のレイヤを塗りつぶす

ということです。


では、最終形のこのスクリプトを実行してみましょう

1. 任意の画像を開いて一部を範囲選択する
1. 任意の画像を開いて一部を範囲選択する

上図のように任意の画像を開き、画像の一部を範囲選択します。

それでは、スクリプトを実行しましょう。 プルダウンメニューの"フィルター(R) -> My Script"を実行します。

2. 入力ダイアログが表示される
2. 入力ダイアログが表示される

上図のように入力ダイアログが表示されるのでColorに任意の色を指定します。 今回の例では黄色を指定しています。

色を指定したら[OK(O)]ボタンを押してください。

3. 範囲選択されている領域が指定された色で塗りつぶされる
3. 範囲選択されている領域が指定された色で塗りつぶされる

上図のように範囲選択されていた領域が指定された色で塗りつぶされます。 また、範囲選択が解除されています。

では、塗りつぶしをさらに実行してみましょう

4. 画像の一部を範囲選択する
4. 画像の一部を範囲選択する

上図のように再度画像の一部を範囲選択します。 1回目とは違う場所・違う形で範囲選択します。

では、スクリプトを再度実行しましょう。 プルダウンメニューの"フィルター(R) -> My Script"を実行します。

5. 入力ダイアログが表示される
5. 入力ダイアログが表示される

上図のように入力ダイアログが表示されるのでColorに任意の色を指定します。 今回の例では青色を指定しています。

色を指定したら[OK(O)]ボタンを押します。

6. 範囲選択されている領域が指定された色で塗りつぶされる
6. 範囲選択されている領域が指定された色で塗りつぶされる

上図のように範囲選択されていた領域が指定された色で塗りつぶされます。 また、範囲選択が解除されています。

では、レイヤーダイアログにあるレイヤ一覧を確認してみましょう。

7. "塗りつぶし" という名称のレイヤしか作成されていない
7. "塗りつぶし" という名称のレイヤしか作成されていない

上図のように増えているのは "塗りつぶし" という名称のレイヤだけです。 2回スクリプトを実行しても、追加されたレイヤは "塗りつぶし" の1つだけで済みました。

  
  

まとめ

入力ダイアログでは、利用者に色を指定させることもできます。 色を指定させるためには、スクリプトに渡す引数の型に SF-COLOR を指定します。 なお、スクリプトに渡す引数の型には以下があります。

スクリプトへの引数の型 意味
SF-IMAGE 画像番号を受け渡す
SF-COLOR 色を受け渡す
※入力ダイアログが開く
SF-VALUE 数値や文字列を受け渡す
※入力ダイアログが開く
※文字列にはSF-STRINGの方が適している
※そのため実質数値にしか使わない
SF-STRING 文字列を受け渡す
※入力ダイアログが開く
SF-FILENAME ファイル名を受け渡す
※入力ダイアログが開く
SF-DIRNAME フォルダ名を受け渡す
※入力ダイアログが開く
SF-TOGGLE オン・オフ状態を受け渡す
※入力ダイアログが開く

Script-Fuでは、範囲選択に関する手続きももちろん用意されています。

手続き 機能
gimp-selection-is-empty 範囲選択されていない状態かを返す
※範囲選択されていない状態ならTRUEを返す
gimp-selection-none 範囲選択を解除する

描画に関する手続きも以下のように用意されています。

手続き 機能
gimp-context-push コンテキスト(描画設定情報)を保存する
※スタックの一番上に積む
gimp-context-pop コンテキスト(描画設定情報)を取り出す
※スタックの一番上から取り出す
gimp-context-set-foreground 描画色を設定する
gimp-drawable-edit-fill 範囲選択されている領域を塗りつぶす
gimp-displays-flush 変更内容を表示に反映する

レイヤ操作に関する手続きには以下があります。

手続き 機能
gimp-layer-new 新たなレイヤを作成しレイヤ番号を返す
※画像とはまだ結びつかない
gimp-image-add-layer 指定されたレイヤを画像に追加する
※画像とレイヤが結びつく
gimp-image-get-layer-by-name 指定された名称のレイヤのレイヤ番号を返す
※見つからない場合は -1 を返す
gimp-image-get-active-layer 選択中のレイヤのレイヤ番号を返す
gimp-image-set-active-layer 指定されたレイヤを選択状態にする
メニュー