3.5. スクリプトを肉付け

さあ訓練を続けましょう。 こんどはスクリプトに機能を加えます。

3.5.1. 新しい画像を生成

先の講義では中身のない関数を作成し GIMP に登録しました。 この講義ではスクリプトに肉付けを行ないます。 スクリプトには新しい画像を作成させ、 ユーザーが指定するテキストを加えてテキストにぴったりな大きさに画像の寸法を調節させるつもりです。

変数の設定や関数の定義、 リストの要素を引き出す方法についてはもう学びましたので、 あとは坂を滑り下りるだけです。 これからなすべきことは GIMP のプロシージャーデータベースで利用可能な関数に慣れ親しみ、 それらの機能を直に呼び出すことがすべてです。 では早速 「プロシージャーブラウザー」 を立て上げてお料理しましょう。

新しい画像を作成するところから始めます。 theImage という新しい変数を作り、 gimp-image-new という GIMP の組み込み機能を実行して得た値を代入するのです。

プロシージャーデータベースのブラウザーによると、 gimp-image-new は画像の幅、 高さ、 型式の 3 つのパラメーターをとります。 画像の大きさはあとでテキストに合わせて変更するので、 とりあえず 10×10 ピクセルの RGB 画像を作成させます。 画像の幅と高さのパラメーターやいくつかの変数はあとでスクリプトが操作するために参照する必要があるのでここで保管しておきます。

        (define (script-fu-text-box inText inFont inFontSize inTextColor)
        (let*
              (
                 ; define our local variables 
                 ; create a new image: (新しい画像を作る局所変数を定義する)
                 (theImageWidth  10)
                 (theImageHeight 10)
                 (theImage (car
                                (gimp-image-new
                                 theImageWidth
                                 theImageHeight
                                 RGB
                                )
                           )
                 )
                 (theText)     ;a declaration for the text (テキストの定義)
                               ;we create later (あとで作成するつもり)
      
[注記] 注記

ここでは RGB 画像を示すために RGB という値を使いました。 代わりに 0 としても同じ結果になりますが、 コードを読む人にとっては RGB と明示した方が説明的で理解し易くなります。

関数を呼び出した結果の値から先頭の要素を引き出しているところにご注目ください。 これは奇妙な感じがします。 というのもデータベースにははっきりとこの関数が返す値はたったひとつ新しい画像の ID 番号だけだと記されているからです。 実は GIMP の関数はたとえ返し値がひとつだけであっても必ずこれをリストにして返します。 ですからそのリストの先頭を引き出してやる必要があるのです。

3.5.2. 画像に新しいレイヤーを追加

画像ができたのでこんどはレイヤーを追加する必要があります。 gimp-layer-new 関数を呼び出して先程作った画像の ID 番号を渡し、 レイヤーを生成させます。 (ここからの説明では関数の中身を全部ここに掲載する代わりに、 追加される行だけを載せます。 最終的なスクリプトの全貌はこの演習の 最後 でご覧いただけます。) これで使う予定の局所変数はすべて宣言し終えましたので、 変数宣言を示す括弧もここで閉じることにします。

        ;create a new layer for the image:
           (theLayer
                     (car
                          (gimp-layer-new
                           theImage
                           theImageWidth
                           theImageHeight
                           RGB-IMAGE
                           "layer 1"
                           100
                           LAYER-MODE-NORMAL
                          )
                      )
            )
         ) ;end of our local variables
      

新しいレイヤーができたので画像に加えなくてはなりません。

        (gimp-image-insert-layer theImage theLayer 0 0)
      

さてここまでにスクリプトが実らせた果実の熟れ具合を見て楽しむために、 つぎの行を追加して新しい空の画像を表示させましょう。

(gimp-display-new theImage)

以上の工作を保存します。 そのあと画像ウィンドウのメニューより フィルターScript-Fuスクリプトを再読み込み させてから、 スクリプトを実行すると新しい画像が開かれるはずです。 画像はゴミだらけ (不規則な色) になっているでしょう。 消去の処理をしていないためです。 さああともう少しです。

3.5.3. テキストを追加

先に進みたいので先程画像を表示させるために追加した行を削除してください。 (もしくはその行の最初にセミコロン;を書き加えてコメントアウトしてください。)

画像にテキストを加える前に、 画像の背景色と描画色を設定してテキストが読み取れる色づかいに設定しなくてはなりません。 これには gimp-context-set-background 関数と gimp-context-set-foreground 関数を使いましょう。

        (gimp-context-set-background '(255 255 255) )
        (gimp-context-set-foreground inTextColor)
      

色がうまく設定できたら、 描画対象を塗りつぶす方法で画像に溢れているゴミを一掃しましょう。

        (gimp-drawable-fill theLayer BACKGROUND-FILL)
      

画像が清められたらつぎはテキストの追加にとりかかります。

        (set! theText
                      (car
                           (gimp-text-fontname
                            theImage theLayer
                            0 0
                            inText
                            0
                            TRUE
                            inFontSize PIXELS
                            inFont)
                       )
        )
      

長い関数呼び出しになっていますが、 プロシージャーデータベースのブラウザーでそれぞれのパラメーターについて見てみればどの項目もありきたりなものばかりです。 要するにここでは新しいテキストレイヤーを作成して変数 theText に代入しているのです。

さてテキストができましたので、 つぎはその幅と高さをつかめば画像とそのレイヤーの寸法をテキストの大きさに合わせられます。

        (set! theImageWidth   (car (gimp-drawable-width  theText) ) )
        (set! theImageHeight  (car (gimp-drawable-height theText) ) )

        (gimp-image-resize theImage theImageWidth theImageHeight 0 0)

        (gimp-layer-resize theLayer theImageWidth theImageHeight 0 0)
      

私もそうでしたが、 描画対象というのはレイヤーとどんな関係にあたるものなのか疑問に思われたことでしょう。 両者の違いについては、 レイヤーやチャンネルやレイヤーマスクや選択範囲などなどあらゆる描画可能なものを描画対象と呼ぶということで説明できます。 レイヤーは特定の描画対象だといえます。 ほとんどの場合その区別は重要ではありません。

画像の準備ができましたので、 また途中経過の表示の行を追加してもよいでしょう。

        (gimp-display-new theImage)
      

以上の工作を保存したらデータベースを読み込み直し、 できたばかりのはじめてのスクリプトを作動させてみましょう。

3.5.4. 手付きフラグを解消

でき上がった画像をファイルに保存せずに閉じようとすると、 GIMP は画像を閉じる前に保存しませんかと尋ねるはずです。 これは画像が手付きになっている、 すなわち保存されていないために起こります。 今回作ったスクリプトの場合は単に試しで画像化してあとは何も加工していないのに毎回こんな風に尋ねられたら面倒です。 しかも同じようなスクリプトならまたしても起こりうる事例なので、 ここは手付きフラグを消すことを考えてみます。

この目的のためには手付きフラグの解消を画像の表示後に行なえばよろしい。

        (gimp-image-clean-all theImage)
      

この処理は手付きの回数を 0 にするので結果的に画像が手付きなしとなります。

このような行を挿し挟むか否かは個人的な好みに委ねられます。 私なら新たな画像を作成するスクリプトの、 今回のようにありきたりの結果が出る場合に限ります。 しかしスクリプトがとても複雑だったり、 既存の画像を加工するものならば、 おそらくこういった機能を使いたい理由がありません。