GIMP いぢり

マニュアル
Grokking the GIMP と GIMP Users Manual (GUM) はとりあえず必読かも。パス操作、Perl-Fu などの詳細や、Dynamic text プラグインみたいな GIMP 1.1 以降のナイスな新機能もバッチリ。
スプラッシュ
GIMP 起動時のロゴ絵はどれもカッチョよくて好きだったけど、まとめて眺めるとなかなか壮観。
イメージマップを作ろう!
適当な画像を開いて、画像の上で右クリック、「フィルタ/Web/ImageMap...」 プラグインを選び、左端の領域指定ツールでクリッカブルにしたい部分を選んで、ダイアログにリンク先 URL なり JavaScript なりを指定して保存すると html ファイルを吐いてくれます。
このファイルを maptest.html とすれば、SSI が有効なサーバなら、
<!--#include file="maptest.html"-->
なんてのを index.html なりのクリッカブルマップをはさみたいところに書いておくだけでおっけー。
SRPM 作ってインストール
する時は、 なりよ。↑の .spec は、もうちょっとちゃんと日本語化した方がいいかも。
Perl-Fu (2000/04)
Perl の Gimp.pm を使ってプラグインを作ってみる。Perl-Fu を使うと、GIMP の作業でよく使う手順を Perl で記述でき、必要なときに何度でも同じ画像処理を行うことができる。また、パラメータをいろいろ変更して処理を行いたい場合にも便利だ。今回はフォント名とそのフォントイメージを、各フォント毎に自動で画像にしてみたい。要は、こんな画像を自動生成しよう、という試み。できあがったプラグインは
% gimptool --install-bin fontsample_m
のようにしてインストールする。

●具体的な Perl-Fu の作り方
まず、GUM の perl_a.html を良く読む。この中から Uni というシンプルなスクリプトをコピーして使ってみる。次に必要な処理を加えていく。作成したプラグインが、新規イメージをつくる場合は register セクションで <Toolbox>/Xtns/ の下に、既存のレイヤーにエフェクトをかける場合は <Image>/Filters/ の下に、それぞれ置くようにするといいだろう。

fontsample_m の解説
#!/usr/bin/env perl

# Gimp.pm モジュールを組み込む
use Gimp qw(:auto);
use Gimp::Fu;

# 実際の処理を行うサブルーチン
sub fontsample {
  # GUI (register 部) から入力されるパラメータを受け取る
  my ($width, $height, $labelfont, $labelcolor, $samplepat, $sampletext, $samplesize, $fgcolor, $bgcolor, $merge, $save, $limit) = @_;
  my $i = 0;
  my $border = 2;

  # xlsfonts コマンドの出力をバッファに入れる
  open(FL, "xlsfonts |");
  my @fontlist = <FL>;
  close(FL);

  foreach (@fontlist) {
    # バッファの中でパターンにマッチするフォントを選ぶ
    if (/$samplepat/ && $i <= $limit) {
      chomp;
      # フォントサイズの設定
      s/--0/--$samplesize/;

      # XLFD からフォントファミリー名を取得
      my $samplefont = $_;
      my $samplelabel = (split(/-/, $samplefont))[2];

      # 新規画像を開く
      my $img = gimp_image_new($width, $height, RGB);

      # Background レイヤーを加える
      my $layer = gimp_layer_new($img, $width, $height, RGB, "background", 100, NORMAL_MODE);
      gimp_image_add_layer($img, $layer, -1);
      gimp_palette_set_background($bgcolor);
      gimp_edit_fill($layer);

      # マッチしたフォントでイメージを描く
      gimp_palette_set_foreground($fgcolor);
      my $sample_layer = gimp_text_fontname($img, -1, 0, 0, " $sampletext ", $border, 1, xlfd_size($samplefont), $samplefont);
      my $sample_x = $width  - gimp_drawable_width($sample_layer)  - 2;
      my $sample_y = $height - gimp_drawable_height($sample_layer) - 2;
      gimp_layer_set_offsets($sample_layer, $sample_x, $sample_y);

      # フォントファミリー名をラベルとして描く
      gimp_palette_set_foreground($labelcolor);
      my $label_layer = gimp_text_fontname($img, -1, 0, 0, "$samplelabel", $border, 1, xlfd_size($labelfont), $labelfont);
      gimp_layer_set_offsets($label_layer, 2, 2);

      # ラベルに影となるレイヤーをつけ、見やすくする
      my $label_layer_copy = gimp_layer_copy($label_layer, 1);
      gimp_image_add_layer($img, $label_layer_copy, 1);
      gimp_selection_layer_alpha($label_layer_copy);
      gimp_selection_grow($img, 2);
      gimp_palette_set_background($fgcolor);
      gimp_edit_fill($label_layer_copy);
      gimp_selection_clear($img);

      # 全レイヤーを統合し、GIF イメージとしてカレントディレクトリに保存する
      if ($merge || $save) {
        my $merged_layer = gimp_image_merge_visible_layers($img, 1);
      }
      if ($save) {
        gimp_convert_indexed($img, 1, MAKE_PALETTE, 256, 1, 1, "Web");
        file_gif_save(RUN_NONINTERACTIVE, $img, -1, "$samplelabel.gif", "$samplelabel.gif", 1, 0, 0, 0);
      }

      $img[$i++] = $img;
    }
  }

  # 作成した全画像を表示して終了
  return @img;
}

# GIMP にこのプラグインについての情報を与え、パラメータ変更用の GUI を生成する
register
  "fontsample_m",            # プラグイン名(プラグインの識別子となるので unique なものに)
  "font sample image",       # 簡単な説明
  "Create a sample image of the font",   # 詳しい説明
  "shackon",                 # 自分の名前
  "shackon (c)",             # copyright
  "2000-04-12",              # 作成した日付
  # GIMP メニュー中の場所
  # (このプラグインは新規画像を作るので Xtns の下に置き、他のプラグインと重ならない unique な名前を指定)
  "<Toolbox>/Xtns/Perl-Fu/Font Sample Multi",
  "*",                       # 適応する画像の種類
  [ # パラメータのリスト(この情報を元に、プラグインを呼び出したときの GUI ダイアログが作られる)
    [PF_INT,    "width", "Image width", 150],
    [PF_INT,    "height", "Image height", 40],
    # フォントファミリー名を描くのに使うフォント名と色
    [PF_FONT,   "labelfont", "Label font", "-adobe-helvetica-bold-r-normal--14-*-*-*-p-*-iso8859-1"],
    [PF_COLOR,  "labelcolor", "Label font color", [255,255,255]],
    # xlsfonts の出力から grep するフォント名の文字列パターン(Perl の正規表現OK)
    [PF_STRING, "samplepat", "Perl regexp pattern of sample font XLFD", "maniax.*fm_"],
    # フォントを使用して描く文字列
    # (なんちゃってカナフォントの場合、ここに「hj]d」と書けば「クマムシ」などとレンダリングされる)
    [PF_STRING, "sampletext", "Sample text", "Hoge"],
    [PF_INT,    "samplesize", "Sample font size", "30"],
    [PF_COLOR,  "fgcolor", "FG color", [24,178,24]],
    [PF_COLOR,  "bgcolor", "BG color", [0,0,0]],
    # できあがった画像のレイヤーを結合するかどうか(save の場合プラグインが自動的に on にする)
    [PF_TOGGLE, "merge", "Merge visible layers", 1],
    # できあがった画像を自動で保存するか、表示するだけにするか
    [PF_TOGGLE, "save", "Save files", 0],
    # xlsfonts の出力が limit を超えたらやめる
    [PF_INT,    "limit", "Lample number of fonts", "100"]
  ],
  # サブルーチンを呼ぶ(名前を最初に上で作ったサブルーチン名に合わせる)
  \&fontsample;

exit main();

●PDB Explorer
やらせたい処理を行う関数を探すために、「Xtns/PDB Explorer」にはお世話になりまくると思う。まず、「Command」欄に、layer などのキーワードを入力すると layer に関する関数が一覧表示される。そこで、必要な機能を持つ関数を選ぶが、関数名は Tab で補完できる。さらに引数も、例えば gimp_image_merge_visible_layers の関数名の後ろでさらに Tab 補完すれば確定していくことができ (これで #define されている値、例えば gimp_convert_indexed の MAKE_PALETTE など、も分かる)、インタラクティブに gimp_image_merge_visible_layers($img, 1) のように使えばよいことが分かる。最後に、この関数の戻値が LAYER なので
my $merged_layer = gimp_image_merge_visible_layers($img, 1);
のように受けてやれば良いことが分かる。

●プラグインの修正
新しいプラグインをインストールした場合は、GIMP を再起動しないと認識されない。プラグインを修正した場合は、通常プラグインを呼び出し直すだけでOKだが、パラメータの数や種類などが変わった場合は、いったん GIMP を終了する必要があり、さらに、
% rm ~/.gimp-1.1/parasiterc
のようにして parasiterc ファイルを消してやらないと、正常に動かないことがあるので注意。
Ruby-Fu
最近 perl より ruby を書くことの方が多くなって、perl のコードを見るのが辛くなってきたのもあって、gimp-1.2.2 + ruby-gimp-0.6.2 の組み合わせが結構幸せだ。

● Photo album (2001/08)
この前の旅行で 1024x768 のデジカメ写真をたくさん撮ったのだが、これを A4 の紙に6枚づつキレイに印刷したいと思ってあまり汎用性のないプラグイン photo_album.rb を書いてみた。いつものように
% gimptool --install-bin photo_album.rb
のようにしてインストールすると、メニューの「拡張(X)/Ruby-Fu/Photo/Album image」に加わるはずである。起動すると以下のようなダイアログが出てくるので、面倒だがファイルセレクタから、横向きでサイズが 1024x768 の(決めうちかよ…)写真を6枚(Photo1〜Photo6)選んでくれ。Make shadow を on にしておくと実行が遅くなるが、もともと重い(画像を縮小してないのでメモリを大量に使う&遅い)プラグインなので、せっかくだしここは on にするのがお勧めである。
OK を押してしばら〜く待っていると、うまくいけば、下のような画像ができるはずである。ちなみに、この↓画像は 15% ぐらいに縮小してあるが実際は 2100x2600 くらいの画像になるので、そのまま印刷しても十分キレイなはずである。

・印刷
印刷と言えば xv でプリンタに出すより gimp で印刷した方が、はるかに出力がきれいだ。PS に変換するときディザとかうまいことやってるのかな。プリンタのパラメータもチューニングできるし、いい感じだ。ただ、この photo_album プラグインでは各画像毎のノーマライズをしていないので、暗い写真と明るい写真が混ざっている場合は、コントラストなど印刷のパラメータを決めるのが難しい。合成する前に各写真の調整は済ましておいた方がいいだろう。

・DRb
それにしても、ファイルダイアログから写真を6枚ずつ選ぶのはえらくメンドウだ。そこで、ダイアログを開く代りに druby を使ってコマンドラインからこのプラグインを実行してみよう。まず、「拡張(X)/Ruby-Fu/dRuby Server/Start...」を選んで GIMP の druby サーバを起動する(このとき表示される「druby://ホスト名:ポート番号」を覚えておく)。次に photo_album-client.rb のようなスクリプトを書いて
% photo_album-client.rb druby://ホスト名:ポート番号 photo1.jpg photo2.jpg photo3.jpg photo4.jpg photo5.jpg photo6.jpg
のように実行すれば GIMP がなにやら勝手に動いて同じ画像を生成してくれる。ついでに印刷までスクリプトに仕込めば、一応完全に自動化できるはずだがやってない。 ちなみに、1ページに写真5枚とか少なめに印刷したい場合は、背景色(白色)で塗り潰した 1050x800 のサイズの画像 dummy.gif なんかを作っておいて、上記の photo6.jpg などの代りに dummy.gif を引数に与えてやる(手抜きプラグインですまん…)。
とりあえずこんなところで。

● Hairline フィルタ (2001/09)
Photoshop 本を見ながら Ruby-Fu でステンレスの表面やドラムの胴にあるようなテクスチャを作るフィルタ hairline.rb を書いてみた。
% gimptool --install-bin hairline.rb
としてインストールしておいて、効果を加えたい画像のレイヤーでマウスの右ボタンを押し、Ruby-Fu/Alchemy/Hairline の順で辿って実行する。

● PSD to JPEG (2002/05)
最近 Photoshop のファイル (.psd) を 1000 枚ほど JPEG (.jpg) に変換する必要に迫られて、久しぶりに Ruby-Fu を使ってみた。
#!/usr/bin/env ruby

require 'gimp'
require 'gimp/fu'
include Gimp

# 変換するためのメソッドを定義する
def psd2jpg(psdimg, jpgimg, comment)
  # 指定された Photoshop ファイルを読み込む
  image = gimp_file_load(RUN_NONINTERACTIVE, psdimg, File.basename(psdimg))
  drawable = image.active_drawable

  # JPEG として保存する
  file_jpeg_save(RUN_NONINTERACTIVE,
		 image, drawable, jpgimg, File.basename(jpgimg),
		 0.75,	# quality
		 0.00,	# smoothing
		 1,	# optimize
		 0,	# progressive
		 comment, # コメント文を埋め込む
		 0,	# subsampling
		 1,	# baseline
		 0,	# restart
		 1	# dct
		 )

  # 後始末
  gimp_image_delete(image)
end

# GIMP に登録する
register(
  'psd2jpg',
  'Convert Photoshop(tm) file to JPEG file',
  'Load a Photoshop(tm) PSD file and save as a JPEG file with comments.'
  'shackon',
  'KATAYAMA Toshiaki <k@bioruby.org>',
  '2002',
  '/Xtns/Ruby-Fu/Conv/Photoshop to JPEG',
  '',
  [
    [RF_FILENAME, 'psdimg', 'Photoshop file name', ''],
    [RF_FILENAME, 'jpgimg', 'JPEG file name', ''],
    [RF_STRING, 'comment', 'Comments', ''],
  ]
) { |psdimg, jpgimg, comment|
  psd2jpg(psdimg, jpgimg, comment)
}

main
メインな部分はこんな感じである。JPEG ファイルには Copyright など自由にコメントが埋め込めるようなので、好きな文を入れられるようにしてある。さらにコメントをファイルに埋め込むだけでなく画像上にも描くようにしたものが完成版 psd2jpg.rb である。いつものようにインストールしておく。
% gimptool --install-bin psd2jpg.rb
さて、これを 1000 回実行するにはやはりマウスをクリックしまくるのではなく druby を使う。GIMP で druby サーバを起動しておき、psd2jpg-client.rb のようなスクリプトを用意して、Photoshop のファイルが置いてあるディレクトリで
% for i in *
do
  psd2jpg-client.rb druby://ホスト名:ポート番号 $i $i.jpg 'Copyright (C) 2002 Fuga Hoge'
done
などとするわけである(zsh や bash の場合)。
しかし良く見ると、このプラグインは読み込むファイル形式は特に指定していないので(笑、名前に反して「GIMP で読み込めるファイル → JPEG で保存」という、割と汎用的な仕上がりになっている気がした…。

[perl] [manual] [splash] (local access only)
Last modified: Thu May 9 19:36:42 2002 Toshiaki Katayama
BioRuby.org