トップ > Script-Fuスクリプトの制作 >
もう少し実用的なスクリプトの例

  

もう少し本格的で実用的なスクリプトの例

この章では、プログラミング言語SchemeおよびScript-Fuプログラミングの基礎について学んできました。 また、前の記事では『もしかしたら役に立つかも』と思える程度の機能を持つスクリプトを制作しました。

この記事では、もう少し本格的で実用的なスクリプトを紹介します。 ここで紹介するスクリプトを参考にすることで、みなさんのGIMP生活がほんの少しでも楽になることを祈っています。

全レイヤを対象にレイヤの大きさを画像の大きさに合わせる

全レイヤを対象に、レイヤの大きさを画像の大きさに合わせます。 ただし、文字レイヤは処理の対象外になります。

  
以下のスクリプトを保存する際のファイル名は何でも構いませんが、他と重複しないファイル名にしてください。 考えるのが面倒なら "myscriptchangealllayerstoimagesize.scm" として保存してください。
  1. ; ==============================================================================
  2. ; [機能]
  3. ; 全レイヤを対象にレイヤの大きさを画像の大きさに合わせる。
  4. ;
  5. ; [補足]
  6. ; 文字レイヤは処理の対象外となる。
  7. ;
  8. ; ==============================================================================

  9. (define (myscriptchangealllayerstoimagesize image)
  10. (let
  11. (
  12. (layer-array 0)
  13. (layer-count 0)
  14. (layer-index 0)
  15. (layer-id 0)
  16. )

  17. (gimp-context-push)
  18. (gimp-image-undo-group-start image)

  19. (set! layer-array (cadr(gimp-image-get-layers image)))
  20. (set! layer-count (car(gimp-image-get-layers image)))

  21. (while (< layer-index layer-count)
  22. (set! layer-id (vector-ref layer-array layer-index))

  23. (if (= (car(gimp-item-is-text-layer layer-id)) FALSE)
  24. (begin
  25. (gimp-layer-resize-to-image-size layer-id)
  26. )
  27. )

  28. (set! layer-index (+ layer-index 1))
  29. )

  30. (gimp-image-undo-group-end image)
  31. (gimp-context-pop)
  32. (gimp-displays-flush)
  33. )
  34. )

  35. (script-fu-register
  36. "myscriptchangealllayerstoimagesize" ; Function Name
  37. "<Image>/Filters/My Scripts/Change All Layers to Image Size" ; Menu Label
  38. "Change All Layers To Image Size." ; Description
  39. "My Name" ; Author
  40. "My Name" ; Copyright
  41. "Sep 25, 2022" ; Date Created
  42. "RGB* GRAY*" ; Image Type That The Script Works On
  43. SF-IMAGE "Image" 0 ; Image ID
  44. )
 

新たに登場した手続きの機能は以下の通りです。

手続き 機能
gimp-item-is-text-layer 指定されたレイヤが文字レイヤかどうかを返す
※文字レイヤならTRUEを返す
gimp-layer-resize-to-image-size 指定されたレイヤの大きさを画像の大きさ(キャンバスサイズ)に合わせる

選択範囲の形状でハイライトを作成する

範囲選択されていない部分を暗くすることで、選択範囲の内側を目立たせます。 Dark Theme?チェックボックスがチェックされている場合は、周りを暗くせずに逆に明るくします。

  
以下のスクリプトを保存する際のファイル名は何でも構いませんが、他と重複しないファイル名にしてください。 考えるのが面倒なら "myscripthilight.scm" として保存してください。
  1. ; ==============================================================================
  2. ; [機能]
  3. ; 選択範囲の形状でハイライトを作成する。
  4. ;
  5. ; [補足]
  6. ; 範囲選択されていない場合はエラーとなる。
  7. ;
  8. ; ==============================================================================

  9. (define (myscripthilight image growradius darktheme)
  10. (let
  11. (
  12. (activelayer-width 0)
  13. (activelayer-height 0)
  14. (hilightlayer-id 0)
  15. )

  16. (gimp-context-push)
  17. (gimp-image-undo-group-start image)

  18. (if (= (car (gimp-selection-is-empty image)) FALSE)
  19. (begin
  20. (if (= darktheme TRUE)
  21. (begin
  22. (set! hilightlayer-id (car (gimp-image-get-layer-by-name image "明")))
  23. )
  24. (begin
  25. (set! hilightlayer-id (car (gimp-image-get-layer-by-name image "暗")))
  26. )
  27. )

  28. (if (= hilightlayer-id -1)
  29. (begin
  30. (set! activelayer-width (car (gimp-image-width image)))
  31. (set! activelayer-height (car (gimp-image-height image)))

  32. (if (= darktheme TRUE)
  33. (begin
  34. (set! hilightlayer-id (car (gimp-layer-new image activelayer-width activelayer-height 1 "明" 25 0)))
  35. )
  36. (begin
  37. (set! hilightlayer-id (car (gimp-layer-new image activelayer-width activelayer-height 1 "暗" 50 0)))
  38. )
  39. )

  40. (gimp-image-add-layer image hilightlayer-id -1)

  41. (gimp-image-set-active-layer image hilightlayer-id)

  42. (if (= darktheme TRUE)
  43. (begin
  44. (gimp-context-set-foreground '(255 255 255))
  45. )
  46. (begin
  47. (gimp-context-set-foreground '(0 0 0))
  48. )
  49. )

  50. (gimp-drawable-fill hilightlayer-id FOREGROUND-FILL)
  51. )
  52. (begin
  53. (gimp-image-set-active-layer image hilightlayer-id)
  54. )
  55. )

  56. (gimp-selection-grow image growradius)
  57. (gimp-edit-cut hilightlayer-id)

  58. (gimp-selection-grow image growradius)
  59. (plug-in-gauss 1 image hilightlayer-id (* growradius 2.5) (* growradius 2.5) 1)

  60. (gimp-selection-none image)
  61. )
  62. (begin
  63. (gimp-message "範囲選択されていません。")
  64. )
  65. )

  66. (gimp-image-undo-group-end image)
  67. (gimp-context-pop)
  68. (gimp-displays-flush)
  69. )
  70. )

  71. (script-fu-register
  72. "myscripthilight" ; Function Name
  73. "<Image>/Filters/My Scripts/Hi-Light" ; Menu Label
  74. "Hi-Light Selection." ; Description
  75. "My Name" ; Author
  76. "My Name" ; Copyright
  77. "April 7, 2016" ; Date Created
  78. "RGB* GRAY*" ; Image Type That The Script Works On
  79. SF-IMAGE "Image" 0 ; Image ID
  80. SF-ADJUSTMENT "Grow Radius" '(4 4 128 1 1 0 0) ; Grow Radius
  81. SF-TOGGLE "Dark Theme?" FALSE ; Dark Theme
  82. )
 

新たに登場した手続きの機能は以下の通りです。

手続き 機能
gimp-selection-grow 選択範囲を広げる
gimp-drawable-fill 塗りつぶす
※手続き gimp-drawable-edit-fill とは異なり選択範囲は考慮しない
gimp-edit-cut 切り取る
plug-in-gauss ぼかす(ガウスぼかし)

選択中のレイヤの影を新たな下位レイヤを作成して落とす

ドロップシャドウと同じ効果です。

  
ドロップシャドウとは、プルダウンメニューの "フィルター(R) -> 照明と投影(L) -> ドロップシャドウ(D)..." で実行される機能のことです。
  
以下のスクリプトを保存する際のファイル名は何でも構いませんが、他と重複しないファイル名にしてください。 考えるのが面倒なら "myscriptdropshadow.scm" として保存してください。
  1. ; ==============================================================================
  2. ; [機能]
  3. ; 選択中のレイヤの影を新たな下位レイヤを作成して落とす。
  4. ;
  5. ; [補足]
  6. ; 作成される影用レイヤの名称は、選択中のレイヤの名称 + "影" となる。
  7. ;
  8. ; ==============================================================================

  9. (define (myscriptdropshadow image shadowradius shadowcolor)
  10. (let
  11. (
  12. (activelayer-name 0)
  13. (shadowlayer-name 0)
  14. (activelayer-id 0)
  15. (shadowlayer-id 0)
  16. (copiedlayer-id 0)
  17. )

  18. (gimp-context-push)
  19. (gimp-image-undo-group-start image)

  20. (set! activelayer-id (car (gimp-image-get-active-layer image)))
  21. (set! activelayer-name (car (gimp-layer-get-name activelayer-id)))
  22. (set! shadowlayer-name (string-append activelayer-name "影"))

  23. (set! shadowlayer-id (car (gimp-image-get-layer-by-name image shadowlayer-name)))

  24. (if (= shadowlayer-id -1)
  25. (begin
  26. ; null
  27. )
  28. (begin
  29. (gimp-image-remove-layer image shadowlayer-id)
  30. )
  31. )

  32. (script-fu-drop-shadow image activelayer-id 0 0 shadowradius shadowcolor 60 FALSE)
  33. (set! shadowlayer-id (car (gimp-image-get-layer-by-name image "Drop Shadow")))
  34. (gimp-image-set-active-layer image shadowlayer-id)

  35. (set! activelayer-id (car (gimp-image-get-active-layer image)))
  36. (set! copiedlayer-id (car (gimp-layer-copy activelayer-id 1)))
  37. (gimp-image-add-layer image copiedlayer-id -1)
  38. (set! copiedlayer-id (gimp-image-merge-down image copiedlayer-id 0))

  39. (set! activelayer-id (car (gimp-image-get-active-layer image)))
  40. (set! copiedlayer-id (car (gimp-layer-copy activelayer-id 1)))
  41. (gimp-image-add-layer image copiedlayer-id -1)
  42. (set! copiedlayer-id (gimp-image-merge-down image copiedlayer-id 0))

  43. (set! activelayer-id (car (gimp-image-get-active-layer image)))
  44. (set! copiedlayer-id (car (gimp-layer-copy activelayer-id 1)))
  45. (gimp-image-add-layer image copiedlayer-id -1)
  46. (set! copiedlayer-id (gimp-image-merge-down image copiedlayer-id 0))

  47. (set! activelayer-id (car (gimp-image-get-active-layer image)))
  48. (set! copiedlayer-id (car (gimp-layer-copy activelayer-id 1)))
  49. (gimp-image-add-layer image copiedlayer-id -1)
  50. (set! copiedlayer-id (gimp-image-merge-down image copiedlayer-id 0))

  51. (set! shadowlayer-id (car (gimp-image-get-layer-by-name image "Drop Shadow")))
  52. (gimp-layer-set-name shadowlayer-id (string-append activelayer-name "影"))

  53. (gimp-layer-resize-to-image-size shadowlayer-id)

  54. (gimp-image-undo-group-end image)
  55. (gimp-context-pop)
  56. (gimp-displays-flush)
  57. )
  58. )

  59. (script-fu-register
  60. "myscriptdropshadow" ; Function Name
  61. "<Image>/Filters/My Scripts/Drop Shadow" ; Menu Label
  62. "Drop Shadow." ; Description
  63. "My Name" ; Author
  64. "My Name" ; Copyright
  65. "April 7, 2016" ; Date Created
  66. "RGB* GRAY*" ; Image Type That The Script Works On
  67. SF-IMAGE "Image" 0 ; Image ID
  68. SF-ADJUSTMENT "Shadow Radius" '(4 4 128 1 1 0 0) ; Shadow Radius
  69. SF-COLOR "Shadow Color" '(255 255 255) ; Shadow Color
  70. )
 

新たに登場した手続きの機能は以下の通りです。

手続き 機能
script-fu-drop-shadow 影を落とす(ドロップシャドウ)
gimp-layer-copy レイヤを複製する
gimp-image-merge-down 下位レイヤと統合する
gimp-layer-set-name レイヤの名称を設定する
gimp-image-remove-layer 指定されたレイヤを削除する

選択範囲の形状で線を引く

ストローク描画と同じ効果です。

  
ストローク描画とは、プルダウンメニューの "編集(E) -> 選択範囲の境界線を描画(S)..." で実行される機能のことです。
  
以下のスクリプトを保存する際のファイル名は何でも構いませんが、他と重複しないファイル名にしてください。 考えるのが面倒なら "myscriptstroke.scm" として保存してください。
  1. ; ==============================================================================
  2. ; [機能]
  3. ; 選択範囲の形状で線を引く。
  4. ;
  5. ; [補足]
  6. ; 範囲選択されていない場合はエラーとなる。
  7. ;
  8. ; [注意]
  9. ; 別途、関数 myscriptdropshadow が必要となる。
  10. ;
  11. ; ==============================================================================

  12. (define (myscriptstroke image brush brushsize brushcolor dropshadow)
  13. (let
  14. (
  15. (activelayer-width 0)
  16. (activelayer-height 0)
  17. (strokelayer-id 0)
  18. (shadowlayer-id 0)
  19. )

  20. (gimp-context-push)
  21. (gimp-image-undo-group-start image)

  22. (if (= (car (gimp-selection-is-empty image)) FALSE)
  23. (begin
  24. (set! strokelayer-id (car (gimp-image-get-layer-by-name image "線")))

  25. (if (= strokelayer-id -1)
  26. (begin
  27. (set! activelayer-width (car (gimp-image-width image)))
  28. (set! activelayer-height (car (gimp-image-height image)))

  29. (set! strokelayer-id (car (gimp-layer-new image activelayer-width activelayer-height 1 "線" 100 0)))
  30. (gimp-image-add-layer image strokelayer-id -1)
  31. )
  32. (begin
  33. ; null
  34. )
  35. )

  36. (gimp-image-set-active-layer image strokelayer-id)

  37. (gimp-selection-grow image (* brushsize))

  38. (gimp-context-set-brush (car brush))
  39. (gimp-context-set-brush-size brushsize)
  40. (gimp-context-set-foreground brushcolor)

  41. (gimp-edit-stroke strokelayer-id)

  42. (gimp-selection-none image)

  43. (if (= dropshadow TRUE)
  44. (begin
  45. (set! shadowlayer-id (car (gimp-image-get-layer-by-name image "線影")))

  46. (if (= shadowlayer-id -1)
  47. (begin
  48. ; null
  49. )
  50. (begin
  51. (gimp-image-remove-layer image shadowlayer-id)
  52. )
  53. )

  54. (myscriptdropshadow image brushsize '(255 255 255))
  55. )
  56. (begin
  57. ; null
  58. )
  59. )
  60. )
  61. (begin
  62. (gimp-message "範囲選択されていません。")
  63. )
  64. )

  65. (gimp-image-undo-group-end image)
  66. (gimp-context-pop)
  67. (gimp-displays-flush)
  68. )
  69. )

  70. (script-fu-register
  71. "myscriptstroke" ; Function Name
  72. "<Image>/Filters/My Scripts/Stroke" ; Menu Label
  73. "Stroke Selection." ; Description
  74. "My Name" ; Author
  75. "My Name" ; Copyright
  76. "April 7, 2016" ; Date Created
  77. "RGB* GRAY*" ; Image Type That The Script Works On
  78. SF-IMAGE "Image" 0 ; Image ID
  79. SF-BRUSH "Brush" '("2. Hardness 025" 100 5 0) ; Brush
  80. SF-ADJUSTMENT "Brush Size" '(4 4 128 1 1 0 0) ; Brush Size
  81. SF-COLOR "Brush Color" '(255 0 0) ; Brush Color
  82. SF-TOGGLE "Drop Shadow?" TRUE ; Drop Shadow
  83. )
 
  
このスクリプトを実行するには前出のスクリプト "myscriptdropshadow.scm" も必要です。

新たに登場した手続きの機能は以下の通りです。

手続き 機能
gimp-context-set-brush ブラシを設定する
gimp-context-set-brush-size ブラシのサイズを設定する
gimp-edit-stroke 選択範囲の境界線を描画する

指定ディレクトリの全てのXCFファイルをJPEGファイルにエクスポートする

指定されたディレクトリに置かれている全てのXCFファイルを対象に、全レイヤを結合した画像をJPEGファイルにエクスポートします。

  
以下のスクリプトを保存する際のファイル名は何でも構いませんが、他と重複しないファイル名にしてください。 考えるのが面倒なら "mybatchscriptexporttojpg.scm" として保存してください。
  1. ; ==============================================================================
  2. ; [機能]
  3. ; 指定されたディレクトリに置かれている全てのXCFファイルを対象に、
  4. ; 全レイヤを結合した画像をJPEGファイルにエクスポートする。
  5. ;
  6. ; [補足]
  7. ; XCFファイルは変更されない。
  8. ;
  9. ; ==============================================================================

  10. (define (mybatchscriptexporttojpg directory quality runonwindows)
  11. (let
  12. (
  13. (filepattern "")
  14. (image 0)
  15. (drawable 0)
  16. (matchedfilelist "")
  17. (matchedxcffile "")
  18. )

  19. (if (= runonwindows TRUE)
  20. (begin
  21. (set! filepattern (string-append directory "\\*.xcf"))
  22. )
  23. (begin
  24. (if (not (string=? (substring directory (- (string-length directory) 1) (- (string-length directory) 0)) "/"))
  25. (begin
  26. (set! directory (string-append directory "/"))
  27. )
  28. )

  29. (set! filepattern (string-append directory "*.xcf"))
  30. )
  31. )

  32. (set! matchedfilelist (cadr (file-glob filepattern 1)))

  33. (while (not (null? matchedfilelist))
  34. (set! matchedxcffile (car matchedfilelist))

  35. (set! image (car (gimp-file-load RUN-NONINTERACTIVE matchedxcffile matchedxcffile)))

  36. (set! drawable (car (gimp-image-get-active-layer image)))

  37. (let
  38. (
  39. (activelayer-id 0)
  40. (xcffilename "")
  41. (xcffilename-length 0)
  42. (jpgfilename "")
  43. )

  44. (gimp-context-push)
  45. (gimp-image-undo-group-start image)

  46. (set! xcffilename(car (gimp-image-get-filename image)))

  47. (set! xcffilename-length (string-length xcffilename))

  48. (set! jpgfilename (substring xcffilename 0 (- xcffilename-length 4)))
  49. (set! jpgfilename (string-append jpgfilename ".jpg"))

  50. (gimp-image-merge-visible-layers image 1)

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

  52. (file-jpeg-save 1 image activelayer-id jpgfilename jpgfilename (/ quality 100) 0 0 0 "" 0 0 0 1)

  53. (gimp-image-clean-all image)

  54. (gimp-image-undo-group-end image)
  55. (gimp-context-pop)
  56. (gimp-displays-flush)
  57. )

  58. (gimp-image-delete image)

  59. (set! matchedfilelist (cdr matchedfilelist))
  60. )
  61. )
  62. )

  63. (script-fu-register
  64. "mybatchscriptexporttojpg" ; Function Name
  65. "<Image>/Filters/My Batch Scripts/Export to JPEG" ; Menu Label
  66. "Export to JPEG File." ; Description
  67. "My Name" ; Author
  68. "My Name" ; Copyright
  69. "February 16, 2022" ; Date Created
  70. "" ; Image Type That The Script Works On
  71. SF-DIRNAME "Load from" "" ; Path of Directory
  72. SF-ADJUSTMENT "Quality" '(95 0 100 1 10 0 0) ; Shrink Radius
  73. SF-TOGGLE "Run on Windows?" FALSE ; For file-glob Regular Expression
  74. )
 

新たに登場した手続きの機能は以下の通りです。

手続き 機能
gimp-file-load ファイルから画像を読み込む
gimp-image-get-filename 開いている画像のファイル名を返す
gimp-image-merge-visible-layers 可視レイヤを統合する
file-jpeg-save JPEG形式でファイルへ出力(エクスポート)する
gimp-image-clean-all 画像の変更済み未保存フラグをクリアする
gimp-image-delete 画像を削除する

Windows上で実行されているかどうかの判断について

このスクリプトでは、Windows上で実行されているかどうかは利用者がチェックボックスで入力します。

それでは不便なので自動的に判別できないか、と考えて思いついたのがファイル /etc/hosts の有無を調べるという方法です。

21行目の、

(if (= runonwindows TRUE)

という制御分を、

(if (= (car (file-glob "/etc/hosts" 1)) 0)

に変更することで自動判別できそうです。

  
  

まとめ

まだまだ紹介できていないGIMPの手続きはたくさんあります。 この記事だけでも、以下の新たな手続きが登場しました。

手続き 機能
gimp-item-is-text-layer 指定されたレイヤが文字レイヤかどうかを返す
※文字レイヤならTRUEを返す
gimp-layer-resize-to-image-size 指定されたレイヤの大きさを画像の大きさ(キャンバスサイズ)に合わせる
gimp-selection-grow 選択範囲を広げる
gimp-drawable-fill 塗りつぶす
※手続き gimp-drawable-edit-fill とは異なり選択範囲は考慮しない
gimp-edit-cut 切り取る
plug-in-gauss ぼかす(ガウスぼかし)
script-fu-drop-shadow 影を落とす(ドロップシャドウ)
gimp-layer-copy レイヤを複製する
gimp-image-merge-down 下位レイヤと統合する
gimp-layer-set-name レイヤの名称を設定する
gimp-image-remove-layer 指定されたレイヤを削除する
gimp-context-set-brush ブラシを設定する
gimp-context-set-brush-size ブラシのサイズを設定する
gimp-edit-stroke 選択範囲の境界線を描画する
gimp-file-load ファイルから画像を読み込む
gimp-image-get-filename 開いている画像のファイル名を返す
gimp-image-merge-visible-layers 可視レイヤを統合する
file-jpeg-save JPEG形式でファイルへ出力(エクスポート)する
gimp-image-clean-all 画像の変更済み未保存フラグをクリアする
gimp-image-delete 画像を削除する
 
メニュー