prevcontentnext


マイクテリーのScript-Fu黒帯道場

著者 マイク テリー

 

Script-Fu達人への道

 

バッタくんは、Gimp を見つけたんだ。その秘密を知りた いって ?

とくに素晴らしいスプリクティング能力を知りたいんじゃな いのかな ? もしかすると、単調でつらい画像編集の自動化の見通しに いらいらしてるとか、たぶん、上手に書かれたスクリプトにしかできない 種類の正確さを自分の仕事に求めているとか....

じゃあ、ここがその場所だね。マイクテリーのScript-Fu黒帯道場はScript-Fuの最近の術をトレーニングできるんだ 。

コースの概要

このトレーニングコースでは、Script-Fuを使うのに必要なScheme基礎を紹介します。そして道具箱のスクリプトへ追加することができる手軽なスクリプトを作り上げます。スクリプトはユーザーにテキストの入力を求め、テキストの正確な大きさを持つ新規画像を作成します。それからテキストの周りにバッファスペースを入れられるようにスクリプトを拡張します。

師範に面会する

正直言って私はまだこの術では帯は黄色で、ある程度のレベルにしかあなたを連れて行くことができません。しかし、一緒に鍛錬し、新境地へ辿りつきましょう。このトレーニングで私が何か重要なことを見落としていたり、明らかにどこかが間違っていたなら、メールを送って私にコンタクトをとって下さい。同様に、トレーニングをどのように改善すべきかについての助言や提案などをお持ちでしたら、それを私に送って下さい。

このトレーニングからあなたが何かを会得することを願っています。あなたはすぐにScript-Fuの達人になるかもしれませんよ!

読者へ

これらのトレーニングセッションは、これからScript-Fuを始める人を想定しています。Gimpがスクリプトでできると聞いた時、私は非常に興味をかきたてられ、すぐに飛び込みたかったです。しかし残念ながら、チュートリアルが乏しく不充分でした。特にSchemeを知りませんでした。私のC/C++の知識の切れ端をSchemeの穴の周りに埋め込もうとしていたおよそ二日後のこと、私はScript-Fuの入門者に、とても緻密で中身が詰まった実演のチュートリアルを書こうと思い立ったのです。

そして現在、実際には、チュートリアルは初心者向けになっています。しかし、もっと学んだら、誰でもScript-Fuの達人になれるように拡張しましょう!あなたの提案や批評を歓迎いたします:

Michael Terry

mterry@soulfry.com

特訓1: Schemeに精通する

 

始める前に...

始める前に、私達がみな同じ道場にいることを確認しておかなければいけません。つまり、Gimpがインストールされていて関数が全て揃っているようにしておなければいけません。最新バージョンのGimpを入手したりインストールして実行する情報源は、Gimpのホームページを参照して下さい。(このチュートリアルはGimp 1.0.0を使用して書かれています。)

Schemeをはじめよう

最初に学ぶべきこと:

· Schemeの全ての構文は括弧()で前後を括る。

次に知らなければいけないこと:

· 関数の名前/演算子は常に括弧の最初の項目で、残りの項目は関数の引数である。

しかし、括弧に囲まれたすべてのものが関数というわけではありません -- リストの項目にもなります -- このことは後回しにしておきます。この記法は関数が全ての先頭に付くので、前置記法と呼ばれています。あなたが前置記法に慣れていたり、(ほとんどのHP電卓のような)逆ポーランド記法を使用する電卓を持っていれば、Scheme表現の書式化に適応するのに何の問題もないでしょう。

理解すべき3番目のこと:

· 算術演算子も関数と考えることができ、計算式を書く時は先頭にリストアップします。

先ほど説明した前置記法から、被演算項が後に続きます。

前置と中置と順ポーランド記法の例

ここは前置中置と、後置記法の違いを説明する簡単な例です。1と3をそれぞれ加算します:

· 前置記法: + 1 3 (Schemeでの方法)

· 中置記法: 1 + 3 ("普通に"書く方法)

· 後置記法: 1 3 + (HP電卓での方法)

Schemeで練習

学んだばかりのことを練習しましょう。まだ起動していなければGimpを起動し、拡張/Script-Fu/コンソールを選んで下さい。これはSchemeで対話的に作業することができるScript-Fuコンソールウィンドウを立ち上げます。瞬時にScript-Fuコンソールが現れるでしょう:

Script-Fuコンソールウィンドウ

このウィンドウの下側が現在のコマンドとタイトルのついた入力欄です。ここで、簡単なSchemeコマンドを対話的にテストすることができます。いくつかの数を足してやることにしましょう:

(+ 3 5)

これを入力してリターンを押すと、ウィンドウの中央に8と期待していた通りの答えが返ってきます。

二つ以上の数ではどうでしょうか?"+"関数は二つ以上の引数をとることができるので、問題ありません:

(+ 3 5 6)

これも期待していた14という答えが返ってきました。

これまでのところ、これで良いです。Script-FuコンソールウィンドウでScheme構文を入力するとすぐに実行に移されました。ここで気を付けなければいけないことがあるのです....

余分な括弧に注意

あなたが私なら、あなたは必要な時にはいつでも余分な括弧を使うことに慣れています。それは複雑な数式を入力していて、読みやすくするために括弧によって区分けしたいような時です。Schemeでは、それら余分な括弧を間違って挿入しないように気を付けなければいけません。例えば、5と6を足し算した結果に3を足し算して7を足したいときには:

3 + (5 + 6) + 7= ?

加算するために+演算子が数字のリストをとることができると知っているので、上の式を下のように変換したくなるかもしれません:

(+ 3 (5 6) 7)

しかし、これは間違っています。思い出して下さい、Schmeの全ての構文は括弧にはじまり括弧でおわるので、Schemeインタプリタはその数字の合計と3を足し算する前にあなたが"5"という名前の関数を呼び出そうとしているのだと解釈してしまいます。

上の計算式を正しく書く方法はこうなります:

(+ 3 (+ 5 6) 7)

適切なスペースであることも確認する

C/C++やPerlやJavaというような、他のプログラミング言語に慣れていれば、正確に表現するために数値演算子の周囲に空白スペースを必要としないことを知っているでしょう。

3+5, 3 +5, 3+ 5

これらは全てC/C++やPerlやJavaコンパイラによって受け入れられます。しかし、これと同じことはSchemeには当てはまりません。Schemeインタプリタにより正しく解釈されるには、Schemeでは数値演算子(やあらゆる関数名や演算子)にスペースが必要です。

そういった先入観を完全に追い払うまで、Script-Fuコンソールで簡単な数式をちょっと練習しておきましょう。

特訓2: 変数と関数

 

そうですか、愛弟子よ、あなたは好奇心が強くて変数と関数について知りたいのですか?トレーニングに前向きですね。私は前向きな姿勢が好きです。

変数

全てのScheme構文は括弧で閉じられていて、関数の名前/演算子がリストの先頭であることが分かりました。それではどのように変数を作成して使うのか、さらに関数をどのように作成して使うのかを知る必要があります。まずは変数から始めます。

変数の宣言

変数宣言として二つの異なる方法がありますが、お勧めの方法はlet*構文を使うことです。他のプログラミング言語に慣れていれば、この概念は局所変数とアクティブな範囲のリストの定義と等価なものです。例えば、二つの変数aとbを宣言し、それぞれを1と2で初期化するには、こう書きます:

 
 


一行で書くと:

(let* ( (a 1) (b 2) ) (+ a b) )

注意: コンソールウィンドウを使用しているのなら、これを一行に収めなければいけません。しかし一般には、スクリプトを読みやすくするためにインデントを入れる習慣をつけておきたいでしょう。これについては空白スペースのセクションでちょっと詳しく述べています。

これは二つの局所変数、abを宣言し、初期化し、それから二つの変数の合計を表示します。

局所変数とは何?

合算する(+ a b)をlet*式の括弧の後ではなく、中に書いたことに気が付いたでしょうか。

これはlet*構文を変数の宣言が有効になっているスクリプトの領域で定義したからです。もし(let* ...)構文の後に(+ a b)構文を入力すれば、変数宣言がlet*構文の中だけで有効なので、エラーになるでしょう。これらがプログラマーが局所変数と呼ぶものです。

let*の一般的な構文

一般的なlet*構文の形式:

(let* ( 変数 ) 式 )

変数のところは括弧の中で宣言されます。例えば、(a 2)です。のところは正当なScheme式です。ここで宣言された変数は妥当なlet*構文の中だけで有効だということを覚えておいて下さい。これらは局所変数なのです。

空白スペース

以前に、 スクリプトを分かりやすく構造化するのに役立つよう、インデントをあなたが使いたいかもしれないという事実を述べました。インデントを取り入れることは良い方針であり、Schemeでは何の問題もありません。空白スペースはSchemeインタープリタでは無視され、スクリプトの中でコードを分かりやすく構造化するのに便利なので、繰り返し適用することができます。しかし、Script-Fuのコンソールウィンドウで作業しているのなら、一行の中に全ての式を入力しなければいけません。つまり、演算子と式の閉じ括弧との間の全てのものを、Scrip-Fuコンソールウィンドウの一行に収めなければならないのです。

変数に新しい値を代入する

一度変数を初期化してしまってからも、後でスクリプト中で変数を変更する必要があるかもしれません。変数の値を変更するにはset!構文を使用します:

(let* ( (theNum 10) ) (set! theNum (+ theNum \ theNum)) )

上の式がすることを想像してみましょう。その後でScript-Fuコンソールウインドウにこれを入力して下さい。

注意: "\"は改行ではないことを表します。改行を無視して(Script-Fuコンソールに入力してEnterを打たないこと)、次の行を続けます。

関数

これであなたは変数の手がかりを手に入れたはずですから、関数の仕事に取りかかりましょう。以下の構文で関数を宣言します:

(define (名前 引数リスト) 式 )

名前のところは、この関数に割り当てられた名前です。引数リストはスペースで区切った引数の名前のリストです。式は呼び出された時に関数が実行する、一連のです。例:

(define (AddXY inX inY) (+ inX inY) )

AddXYが関数の名前で、inXinYが変数です。この関数は二つの引数をとってお互いを加算します。

あなたが(C/C++、Java、Pascalなどのような)他の形式言語でプログラミングをしたことがあれば、他のプログラミング言語と比較した時にこの関数定義には二つのことが抜けていることに気付くかもしれません。

· 第一に、引数が"型"を持っていない(つまり、引数が文字列としてなのか、整数としてなのか、などを宣言していない)ことに気が付きます。Schemeは型のない言語です。これはお手軽であり、スクリプトを手早く書くことができます。

· 第二に、関数の"返り値"がどうなのかについて心配する必要がないことに気が付きます。最後の構文がこの関数の呼ばれた時の"返り値"です。コンソールの中に関数を入力して、このようなことをやってみて下さい:

(AddXY (AddXY 5 6) 4)

特訓3: リスト、リスト、リスト、さらにリスト

 

変数と関数で修行を積みました。若きScript-Fuの修行者よ、Schemeのリストの泥沼に入らなければならなくなりました。挑戦の準備は整っていますか?

リストの定義

リストについて話す前に、アトムリストとの違いについて知っておく必要があります。

先ほどの特訓で変数を初期化したときに、すでにアトム値を見ています。アトム値は単独の値です。だから例えば、構文に続けて変数"x"に単独の値8を代入することができます:

(let* ( (x 8) ) x)

(xに値を割り当てて出力するため、最後に式xを追加しました。普通はこんなことする必要などありません。まるで関数のようにlet*が作用していることに注意して下さい。最後の構文の値が返り値です。)

変数は一つの値とは限らず、リストの値を参照しても構いません。変数xにリストの値135を割り当てるには、こう入力します:

(let* ( (x '(1 3 5))) x)

Script-Fuコンソールに両方の構文を入力してみると、どのように返されるか分かるでしょう。前者の構文を入力してみると、こんな結果が返ってくるだけです:

8

しかし後者の構文を入力した時には、下の結果が返ってきます:

(1 3 5)

8が返ってきた時には、xがアトム値8を持っていることを知らせています。しかし、(1 3 5)が返ってきた時には、xが一つの値ではなく、リストの値を持っていることを知らせています。リストの宣言や割り当てや出力結果にはコンマが無いことに注意して下さい。

リストを定義する構文はこれ:

'(a b c)

abcのところはリテラルです。括弧の後に続くものが関数や式ではなく、リテラル値のリストであることを示すためにアポストロフィー(')を使います。

空っぽのリストはこのように定義することができます:

'()

もしくはシンプルに:

()

リストは他のリスト同じように、アトム値を持つことができます:

 
 

最初のアポストロフィーの後には、もはや内部のリストを定義する時のアポストロフィーを使う必要がないことに注意して下さい。Script-Fuコンソールに次々とコピーして、返ってくるものを見て下さい。

あなたは返ってくる結果が一つのリストではなく、リテラル("The Gimp")のリストや、リスト(1 2 3)、などのようなアトム値であることに気付くはずです。

リストの考え方

リストが"先頭"と"末尾"で構成されていると考えることは便利です。先頭はリストの最初の要素で、末尾はリストの残りの要素です。リストに追加する方法やリストの要素にアクセスする方法を論じる時になれば、これがなぜ重要なのか分かるでしょう。

結合を通してリストを作る
(Cons 関数)

あなたが出会う一般的な関数の一つはcons関数です。これは、値に続けて二番目の引数にリストをとります。先程のセクションから、リストが要素(先頭)と残りのリスト(末尾)の合成だと考えるよう提案しました。これが正にcons関数の方法なのです。consはリストの先頭に要素を追加します。従って、下のようにリストを作成することができます:

(cons 1 '(2 3 4) )

その結果、リストは (1 2 3 4) となります。

一つの要素があるリストを作成することもできます:

(cons 1 () )

想像できるように、リテラルの代わりに以前に宣言した変数を使うことができます。

リスト関数を使ってリストを定義する

リテラルや以前に宣言した変数で構成されるリストを定義するには、list関数を使います:

(list 5 4 3 a b c)

これは変数abcによって拘束された値を持つリストを構成して返します。例:

 
 

このコードは、リスト(5 4 3 1 2 3)を作成します。

リストの中の値にアクセスする

リストの中の値にアクセスするには、それぞれリストの最初の要素と、リストの残りの要素を返す関数、carcdrを使います。これらの関数は私が以前に言った概念、先頭と末尾にリストを分割します。

car 関数

carはリストの最初の要素(リストの先頭)を返します。リストが空っぽでない必要があります。従って、下はリストの最初の要素を返します:

(car '("first" 2 "third"))

これはこうなります:

"first"

cdr 関数

cdrは最初の要素に続く残りのリスト(リストの末尾)を返します。リストに一つだけしか要素がなければ、空のリストを返します。

(cdr '("first" 2 "third"))

返ってくるのは:

(2 "third")

以下に対しては:

(cdr '("one and only"))

返ってくるのは:

()

リストの他の要素にアクセスする

よし、できたかな。リストの残りの要素と同じようにリストの最初の要素を手に入れることができますが、リストの二番目、三番目や四番目やその他の要素にアクセスするのはどうするのでしょうか?アクセスするための"便利"な関数がいくつか存在します。例えば、リストの末尾の先頭の先頭にアクセスする(caadr)や、リストの末尾の末尾にアクセスする (cddr)などがあります。

基本的な命名規則は簡単です。aとdはリストの先頭と末尾を表しています。だから

(car (cdr (car x) ) )

これはこのように書くことができます:

(cadar x)

リスト関数の完全なリストを表示するために、Script-Fuによって使われているSchemeバージョンの利用可能な関数をリストアップしている付録Cを参照して下さい。

リストにアクセスする関数をちょっと練習するために、以下を入力してみて下さい(コンソールを使っているなら、一行に全てを収めて下さい)。リストのそれぞれの要素にアクセスするためにcarcdrの異なる亜種を使うのですよ:

 
 

二つの関数を呼び出して、リストの数値3にアクセスしてみて下さい。もしできたなら、あなたはScript-Fuの達人に一歩近付いているのです!

特訓4: 最初のScript-Fuスクリプト

 

休憩して息を整える必要がありますか?え、必要ない?では第四段階の特訓に進みましょう -- 最初のScript-Fuです。

テキストボックススクリプトを作る

Gimpで行う最も一般的な操作の一つが、ウェブページや、ロゴや、何か他のもののために文字付きのボックスを作ることです。しかし、はじめから初期画像をどのくらい大きく作れば良いのか知りません。テキストがどのくらいの間隔で必要なフォントとフォントサイズを塗りつぶすのか知りません。

Script-Fuの達人(と弟子)はこの問題がScript-Fuで簡単に解決して自動化できることをすぐに悟るでしょう。

ユーザー入力の一行テキストの周囲に適度にフィットする、適切な大きさの画像を作るテキストボックスというスクリプトを作ります。ユーザーにフォントフォントサイズ文字色も選択させましょう。

はじめよう

スクリプトの編集と保管

これまでは、Script-Fuコンソールで作業をしていました。しかし今回からは、スクリプトテキストファイルの編集に移ることになります。

あなたのスクリプトを置く場所は環境によりけりです。Gimpのデフォルトのスクリプトディレクトリにアクセスしているなら、スクリプトをそこへ置くことができます。しかし、標準インストールスクリプトから独立しておくために、自分のスクリプトは自分の個人的なディレクトリに置いておきたいでしょう。

Gimpがあなたのホームディレクトリに作った.gimpディレクトリの中で、scriptsと呼ぶディレクトリが見付かるはずです。Gimpは自動的にあなたの.gimpディレクトリのscriptsディレクトリを探して、Script-Fuデータベースにこのディレクトリのスクリプトを追加します。ここにあなたの個人的なスクリプトを置くようにしましょう。

最低限の必需品

全てのScript-Fuスクリプトは、スクリプトのメイン関数である関数を少なくとも一つは定義します。これが作業するところです。

全てのスクリプトはプロシージャデータベースにも登録しなければならず、登録することでGimpの中からそのスクリプトにアクセスすることができるようになります。

まず最初に、メイン関数を定義しましょう:

ここで、後で対応するテキスト、フォント、フォントのサイズ、テキストの、の四つの引数をとるscript-fu-text-boxと呼ぶ新しい関数を定義します。関数は今のところ中身がないので、何もしません。今のところはこれで良いです。新しいものは何も、何も望んでいません。

命名規則

Schemeの命名規則はハイフン付きの文字の方が好まれているようなので、関数の命名をそれに倣いました。しかし、引数で規定することから出発しています。引数と変数を説明的な名前にする方が私は好きです。よって引数に"in"の接頭辞を加えました。こうすればこれがスクリプトの中で作成されたものではなく、スクリプトに渡された値であることが一目で判ります。私はスクリプトの中で定義した変数には接頭辞に"the"を使います。

関数をリストアップすると、プロシージャデータベースにリストアップされる時にscript-fuの下で全てが表示されるので、スクリプトの関数にscript-fu-abcと名前を付けることをGimpが規定しています。これはプラグインをスクリプトと区別することにも便利です。

関数の登録

それでは、Gimpに関数を登録しましょう。これは関数script-fu-registerを呼び出すことで行います。Gimpがスクリプトを読み込む時、プロシージャデータベースにスクリプトを登録するこの関数を実行します。スクリプトの中の任意の場所にこの関数コールを置くことができますが、普通は他の全てのコードの後の、最後に置きます。

ここにこの関数の登録を一覧表示します(すぐ後でこの全ての引数の説明をします):

 
 

スクリプトディレクトリに.scm接尾辞を付けたテキストファイルにこれらの関数を保存したら、拡張|Script-Fu|再読み込みを選びます。この新しいスクリプトは拡張|Script-Fu|Text|Text Boxとして現れます。

 
 

この新しいスクリプトを呼び出しても、もちろん何もしませんが、スクリプトを登録した時に作成したプロンプトを表示することができます(何をしたのかに付いての詳しい情報は次回カバーします)。

 
 

最後に、DBブラウザ(プロシージャデータベースブラウザ、拡張|DBブラウザ)を呼び出せば、データベースに今回のスクリプトが現れていることに気付くでしょう。

 
 

スクリプトを登録する手順

Gimpにスクリプトを登録するために、関数script-fu-registerを呼び出し、いくつかの必須の引数で埋めて、それぞれの引数の説明とデフォルト値とともにスクリプト自身の引数を追加します。

必須の引数

· 定義した関数の名前。これはスクリプトを呼び出した時(スクリプトに入った時点)に呼び出される関数です。同じファイルの中に追加関数を定義して、Gimpが呼び出す関数がどれなのか知る必要があるで、これは必要です。この例では、登録した一つの関数text-boxだけが定義されています。

· スクリプトが挿入されるメニューの位置。スクリプトの正確な位置を道具箱右クリックのどちらかのパスをルートに持ち、Unixのパスのようにして指定します。

スクリプトが既存の画像を操作するのでなければ(つまりこのText Boxスクリプトが作るような、新規画像を作成するもの)、道具箱メニュー -- これはGimpのメインウィンドウ(全てのツールがあるところ: 選択ツール、虫めがね、など)のメニューです -- に挿入したいでしょう。

スクリプトが編集済みの画像に作用するものなら、開いてある画像で右クリックした時に現れるメニューの中に挿入したいでしょう。パスの残りの部分は、メニューリストと、メニュー、サブメニューを示します。よって、道具箱の拡張メニューのScript-FuのTextメニューにテキストボックスのスクリプトを登録しました(拡張|Script-Fu|Text|Text Box)。

お気付きかもしれませんが、初めての時にはScript-FuのサブメニューにはTextサブメニューが存在しません。Gimpはメニューがまだ存在していなければ自動的に作成します。

· スクリプトの説明。これがどこで表示されるのかについて、私ははっきり分かりません。

· あなたの名前 (スクリプトの著者)。

· 著作権情報。

· スクリプトが作られた日付。もしくはスクリプトの最終リビジョン

· スクリプトが作用する画像の種類。これは次のどれでも構いません: RGB, RGBA, GRAY, GRAYA, INDEXED, INDEXEDA。または、全くなくても構いません。この場合は、画像を作成するときなので、作用する画像の種類を決める必要がありません。

スクリプトの引数を登録する

必要な引数をリストアップしたら、次はスクリプトが必要な引数に対応する引数をリストアップする必要があります。引数をリストアップする時の、その種類が何であるかのヒントをあげましょう。これはユーザーがスクリプトを選択した時にポップアップするダイアログのための引数です。デフォルトの値も用意しておきます。

登録工程のこのセクションは下記の書式を持っています:

引数の種類 "プロンプトのテキスト" "デフォルトの値"

サンプルも加えたそれぞれの引数を表 43.1にリストアップします。

表 43.1引数一覧

引数の種類

説明


SF-VALUE 数字を文字列を受け付ける。デフォルトのテキストのために引用符をエスケープしなければならない。 SF-VALUE "Text:" "\"Some text\"" SF-VALUE "A number:" "34"
SF-COLOR この変数で必要とする色を表す。 SF-COLOR "Color:" '(0 0 0)
SF-TOGGLE ブーリアン値を得るためのチェックボックスを表示する。 SF-TOGGLE "Resize?" TRUE
SF-IMAGE スクリプトが開いてある画像に作用するものなら、必要な引数の後にこれを最初の引数にしなければならない。Gimpはこの引数で画像への参照を渡す。 SF-IMAGE "The image" 0
SF-DRAWABLE スクリプトが開いてある画像に作用するものなら、SF-IMAGE引数の後にこれを二番目の引数にしなければならない。これはアクティブレイヤーを参照する。Gimpはこのパラメータでアクティブレイヤーへの参照を渡す。 SF-DRAWABLE "The layer" 0


若き弟子よ、情報が大量にあったので、休息を取りましょう。

特訓5: スクリプトに中身を与える

 

愛弟子よ、素晴らしい集中でしたね。それでは、特訓を続けてスクリプトに機能を追加しましょう。

新規画像の作成

前回の特訓で、空の関数を作成してGimpに登録しました。この特訓では、スクリプトに機能性を提供したいですね。新規画像を作成して、そこにユーザーのテキストを追加して、テキストの正確な大きさに合わせてリサイズしたいのです。

一度変数を設定し、関数を定義し、リストのメンバにアクセスする方法を知ってしまえば、残りは全て下り坂です。やらなければならないことは、Gimpのプロシージャデータベースで利用可能な関数に慣れて、それらの関数を直接呼び出すことです。さぁDB ブラウザを起動して、料理してしまいましょう!

新規画像を作成することからはじめましょう。新しい変数、theImageを作成し、Gimpのビルトイン関数gimp-image-newを呼び出した結果を代入します。

 
 

DBブラウザで見て分かる通り、関数gimp-image-newは三つの引数をとります。画像の高さと画像の種類です。後で画像をテキストにフィットするようにリサイズするので、10x10 RGB 画像を作成しましょう。後からスクリプトの参照と操作ができるよう、変数にも画像の幅と種類を保管しておきます。


 
 

注意: 画像がRGBイメージであることを指定するために、値RGBを使いました。0を使うこともできるのですが、RGBの方がコードをちょっと見た時により説明的です。

あなたは関数コールの結果の先頭を取り出したことにも気付くではずです。奇妙に思えるかもしれませんが、これはデータベースが明示的にただ一つの値、即ち、新しく作成した画像のIDだけを返すことを伝えているのです。従って全てのGimpの関数は、たとえリストに一つの要素しかなくても、リストを返します。そのためリストの先頭を取り出してやる必要があるのです。

画像に新規レイヤーを追加する

画像ができたので、これにレイヤーを追加してやる必要があります。レイヤーを作成するためにgimp-layer-new関数を呼び出し、作成したばかりの画像のIDを渡します(これから後は、完全な関数をリストアップする代わりに、追加している行だけをリストアップします。あなたは完全なスクリプトをここで見ることができます)。使用する全ての局所変数が宣言されているので、変数宣言の終わりを表す括弧を閉じておきます:

 
 

新規レイヤーを作成したら、これを画像に追加してやる必要があります:

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

今ちょっと試してみて、この時点までの作業の仕上り具合を見ることにしましょう。新しい、空っぽの画像を表示するために、この行を追加します:

(gimp-display-new theImage)

作業を保存して、拡張/Script-Fu/再読み込みを選び、スクリプトを実行すると、新規画像がポップアップするはずです。まだ消去していないので、これには多分ゴミ(ランダムな色)が含まれているでしょう。もう一息、あとちょっとです。

テキストの追加

先程の画像を表示する行を削除します(もしくは行の最初の文字として;を付けてコメントアウトします)。

画像にテキストを追加する前に、ユーザーが指定した色で文字が現れるよう、背景色前景色を設定する必要があります。gimp-palette-set-back/foreground関数を使います:

(gimp-palette-set-background '(255 255 255) )

(gimp-palette-set-foreground inTextColor)

カラープロパティを設定したら、現在画像にあるゴミを消去しましょう。画像の全てを選択し、消去を呼び出します:

(gimp-selection-all theImage)

(gimp-edit-clear theImage theLayer)

(gimp-selection-none theImage)

画像をクリアして、テキストを追加する準備が整いました:
長い関数コールですが、DBブラウザで関数のエントリを探しながら引数を調べればそれほど難しくありません。基本的な手順は、新しいテキストレイヤーを作成して、変数theTextに割り当てただけです。

これでテキストができました。その高さを入手して、画像と画像のレイヤーをテキストの大きさへリサイズします:

 
 

あなたが私なら、レイヤーと比較した時のドロアブルとは何だろうかと不思議に思うでしょう。二つの違いは、ドロアブルが何でも書き込めるもので、レイヤーはドロアブルの特別なバージョンです。ほとんどの場合、その違いはそれほど重要ではありません。

これで画像にテキストが入りました。表示行にもう一度追加しましょう:

(gimp-display-new theImage)

作業を保存し、データベースに再読み込みして、あなたの最初のスクリプトを実行しましょう!図43.7のようになるはずです。

 
 

ダーティフラグを消去する

最初にファイルに保存すること無く作成した画像を閉じようとすると、Gimpは画像を閉じる前に作業を保存したいかどうかを尋ねてきます。こう尋ねられるのは、画像がダーティとしてマークされている、つまり保存されていないからです。このスクリプトのように、テスト実行しているだけで結果画像に何も追加したり変更しない時には迷惑なだけです。そこで、単純なスクリプトでは作業を簡単に再現できるように、ダーティフラグを取り除くことが大切です。

これをするには、画像を表示した後でダーティフラグを消去することができます:

(gimp-image-clean-all theImage)

これでダーティカウントは0になり、"クリーン"な画像になりました。

この行を追加するかどうかは個人的な嗜好によります。この場合では結果が重要でなかったので、新規画像を作成するスクリプトでこれを使いました。あなたのスクリプトが非常に複雑であったり、既存の画像に作用するものなら、この関数を使いたくないかもしれません。

特訓6: テキストスクリプトボックスの拡張

 

熱心な弟子よ、あなたの意思と決意を止められません。だから特訓を続けましょう。

正確にアンドゥを処理する

スクリプトを作成している時、ユーザーがスクリプトのアクションで間違いを犯した時のためにアンドゥできる能力を与えたいでしょう。これは画像を操作するコードの前後にgimp-undo-push-group-startgimp-undo-push-group-end関数を呼び出すことで簡単に行えます。後で操作をアンドゥすることができるようにする、Gimpが画像への操作の記録の開始と停止する時を知らせる構文のことだと考えることができます。

完全に新規画像を作成するものなら、既存の画像を変更しないのでこれらの関数を使っても意味がありません。しかし、既存の画像を変更する時には、ほぼ確実にあなたはこれらの関数を使いたいでしょう。

これを書いている時点では、スクリプトのアンドゥは、それらの関数を使った時にはほとんど欠点がありません。しかし、時々全てのものをアンドゥするとトラブルがあるようです。さらに、それらの関数を呼び出さない別のスクリプトを呼び出した時に、最も困難な時に遭遇するあるようです。

スクリプトをもうちょっと拡張する

今のところ、テキストボックスを作成する、とてもお手軽で優しいスクリプトがあります。これに二つの関数を追加しましょう:

· 現在、画像はテキストの周囲に正確にフィットしてリサイズされています。そこには(たとえ多くのスクリプトが必要に応じて自動的に画像をリサイズするとしても)ドロップシャドウや特殊効果のような何かを入れる余地がありません。テキストの周囲にバッファを追加して、合成したテキストの大きさのパーセントとしてどのくらいのバッファを追加するかをユーザーに指定させましょう。

· このスクリプトはテキストを扱う他のスクリプトで簡単に使用することができます。他のスクリプトがこのスクリプトを呼び出して作成した画像とレイヤーを使えるように、画像とレイヤーを返すよう拡張しましょう。

引数を変更して関数に登録する

ユーザーにバッファの量を指定させるため、関数に引数を追加して関数を登録しました:


 
 

新しいコードを追加する

二ヶ所にコードを追加するつもりです。画像をリサイズする直前と、スクリプトの最後です(新規画像とレイヤーとテキストを返すため)。

テキストの幅と高さを入手した後で、ユーザーによって指定されたバッファ量をベースにして値をリサイズする必要があります。ユーザーが追加するバッファのパーセントとして"200"のような値を入力できなければならない理由が無いので、また、そんなことができたら恐ろしいので、エラーチェックの確認をすることがないよう、0-100%の範囲にします。

 
 

ここでやっていることの全ては、テキストの高さがベースのバッファの設定と、新規画像の幅と高さの両方に二回バッファを追加することです(テキストの両側にバッファを追加する必要があるので、両方の方向に二回追加しています)。

こうしてバッファを持つ画像をリサイズしました。次に画像の中のテキストを中央寄せする必要があります。これは(theBuffer, theBuffer)の座標(x, y)にテキストを移動することによって行います。この行をレイヤーと画像をリサイズした後に追加しました:

 
 

最初に戻って、スクリプトを保存します。そしてデータベースを再読み込みした後でこれを試してみましょう。図43.8のようなウィンドウがあるはずです。

 
 

残ったものは、画像と、レイヤーと、テキストレイヤーです。画像を表示した後で、この行を追加します:

(list theImage theLayer theText)

これは関数の最後の行で、このリストを作成することで、このスクリプトを利用したい他のスクリプトから利用できるようになります。

別のスクリプトで新しいテキストボックススクリプトを使うために、下のようなものを書くことができます:

 
 

おめでとう、愛弟子よ。きみはこのまま行けば、Script-Fuの黒帯です!


prevcontentnext


Frozenriver Digital Design
http://www.frozenriver.nu
Voice: +46 (0)31 474356
Fax: +46 (0)31 493833
support@frozenriver.com
Publisher Coriolis
http://www.coriolis.com