ランディネットワークの BLOG

GIMP のスクリーンショットを撮影する関数 pdb.plug_in_screenshot() を検証してみた

Created at:
Category: GIMP

ブログなどの記事を書くときに、スクリーンショットで撮影した画像を載せることがあると思います。

そのときに、スクリーンショットを保存して、画像処理ソフトで開いたファイルの必要な部分だけトリミングを行っていますが、このルーティンワークは画像の枚数が多くなると中々手間がかかります。

そこで、これらの作業を画像処理ソフト GIMP を使って自動で処理を行う Python-Fu のスクリプトを作ってみました。

開発環境

  • GIMP 2.10.18

screenshot 関数の検証

GIMP の Python-Fu でスクリーンショットを取得する関数は pdb.plug_in_screenshot() です。

この関数に引数を設定することで様々なモードでスクリーンショットを撮影することができます。

しかし、この関数の使い方を調べてみても日本語で説明しているサイトは少ないです。

まずは、この関数を使うときの引数について検証してみました。

引数の個数について

pdb.plug_in_screenshot() 関数を GIMP のプロシージャーブラウザーで検索してみると引数が7つあることがわかります。

※プロシージャブラウザーは GIMP のヘルプ ー> プロシージャーブラウザーで起動できます。

引数の名前   データ型   引数の説明
run-mode INT32 The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }
shoot-type INT32 The Shoot type { SHOOT-WINDOW (0), SHOOT-ROOT (1), SHOOT-REGION (2) }
window-id INT32 Window id for SHOOT-WINDOW
x1 INT32 Region left x coord for SHOOT-REGION
y1 INT32 Region top y coord for SHOOT-REGION
x2 INT32 Region right x coord for SHOOT-REGION
y2 INT32 Region bottom y coord for SHOOT-REGION

GIMP の Python コンソールを起動してこの screenshot 関数を試してみます。

※ GIMP の Python コンソールは、フィルター ー> Python-Fu ー> コンソールで起動できます。

関数に引数(とりあえず値は0)を7つ渡して実行すると次のようなエラーが発生してしまいます。

>>> pdb.plug_in_screenshot(0, 0, 0, 0, 0, 0, 0)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: wrong number of parameters

ここで引数を一つ減らして関数を実行してみます。

今回は、対話式で関数を実行しているので、関数実行後にマウスのポインタが十字に変わります。

マウスで適当な場所をクリックすると処理が行われます。

>>> pdb.plug_in_screenshot(0, 0, 0, 0, 0, 0)
<gimp.Image '[名称未設定]'>

エラーが発生しなくなりました。

理由はわかりませんが、 pdb.plug_in_screenshot() 関数の引数の個数は6個にしないといけないみたいです。

各引数の値について

run-mode(動作モード)

screenshot 関数の1個目の引数 run-mode を変更したいと思います。

この引数で動作モードを選択できます。

  • 0 : 非対話式
  • 1 : 対話式

今回は、作業を自動化することが目的なので、非対話式を選択して関数を実行してみます。

次のコードでインタラクティブに実行することが確認できました。

>>> pdb.plug_in_screenshot(1, 0, 0, 0, 0, 0)
<gimp.Image '[名称未設定]'>

shoot-type(撮影タイプ)

screenshot 関数の2個目の引数 shoot-type を変更してみます。

この引数で撮影タイプを選択できます。

  • 0 : 画面
  • 1 : 全画面
  • 2 : 選択範囲

実行するコードは次のとおりです。

shoot-type = 0 のとき(画面を撮影)
img = pdb.plug_in_screenshot(1, 0, 0, 0, 0, 0)
disp = pdb.gimp_display_new(img)
shoot-type = 1 のとき(全画面を撮影)
img = pdb.plug_in_screenshot(1, 1, 0, 0, 0, 0)
disp = pdb.gimp_display_new(img)
shoot-type = 2 のとき(選択範囲を撮影)

※選択範囲の引数には適当な値を入れています。

img = pdb.plug_in_screenshot(1, 2, 100, 100, 500, 500)
disp = pdb.gimp_display_new(img)

しかし、上記3つのコードの実行結果では、どれも同じ全画面での撮影になってしまいました。

pdb.plug_in_screenshot() 関数の実行結果
pdb.plug_in_screenshot() 関数の実行結果

再びプロシージャーブラウザーに戻って plug-in-screenshot を検索してみると、「追加情報」に原因が書かれています。

On Mac OS X or on gnome-shell, when called non-interactively, the plug-inonly can take screenshots of the entire root window.

gnome-shell 環境で screenshot 関数を非対話式で実行したときは、全画面(デュアルディスプレイの場合は2画面)のスクリーンショットを取得するようです。

これでは、私が使っているデュアルディスプレイの開発環境では常に2画面の横長のスクリーンショットが撮影されてしまいます。

そこで、デュアルディスプレイの2画面のうち片方の画面だけのスクリーンショットが取得できるように、他の関数も使ったスクリプトを作成してみます。

select, copy, paste 関数の使用

select 関数

pdb.gimp_rect_select(img, 0, 0, 1920, 1080, 2, False, 0)

この関数では、引数で指定した範囲を矩形選択する処理を行います。

2番目から5番目の引数に矩形選択する範囲を設定します。

今回は、2画面のうち左側の画面だけを選択できるように、範囲を設定します。(ディスプレイは解像度1920*1080のものを使っています。)

7番目と8番目の引数(feather, feather-radius)は選択範囲とその周囲の境界をぼかす設定を行います。

今回は境界ぼかしを使わないので、引数の値はそれぞれ False0 に設定しておきます。

※今回は矩形範囲選択の関数を使いましたが、他にも多角形や楕円の範囲選択を行う関数があります。

  • 多角形範囲を選択する関数   pdb.gimp_select_polygon()
  • 楕円範囲を選択する関数   pdb.gimp_select_ellipse()

copy 関数

pdb.gimp_edit_copy(img.layers[0])

この関数では、引数で指定した画像の Layer をコピーします。

png, jpg 形式の画像ファイルには Layer が一つしかないので、 layers[0] でアクセスします。

paste 関数

new_img = pdb.gimp_edit_paste_as_new_image()

この関数では、コピーした画像を貼り付けます。

作成したスクリプトの実行

上記に記載した関数をまとめると、次のコードになります。

今回はスクリプトを登録しないので、GIMP の Python コンソールでコードを実行します。

選択範囲のスクリーンショットを取得して表示するスクリプト

img = pdb.plug_in_screenshot(1, 0, 0, 0, 0, 0)
pdb.gimp_rect_select(img, 0, 0, 1920, 1080, 2, False, 0) #選択範囲を各自で設定する
pdb.gimp_edit_copy(img.layers[0])
new_img = pdb.gimp_edit_paste_as_new_image()
pdb.gimp_display_new(new_img)
選択範囲のスクリーンショットを取得して表示するスクリプトの実行結果
選択範囲のスクリーンショットを取得して表示するスクリプトの実行結果

select 関数の引数で選択範囲を変えることで、様々な場面に応用ができます。

参考文献

この記事は以下のサイトを参考にしています。