プログラムでおかえしできるかな

定年を過ぎて何かの役に立てないかなと始めた元SEのブログです

Python-Fuスクリプトでバッチ処理【GIMP】

このエントリーをはてなブックマークに追加

Python で RPA のプログラムを作っていて、GIMP も操作できないかと思いました。
残念ながら、RPA の pywinauto では GIMP の制御ができませんでした。
代わりに、GIMP 付属の Python-Fu スクリプトバッチ処理にしました。
基本的な作り方を紹介します。

目次

GIMPスクリプトPython-Fu

GIMPPython-Fu とは、GIMP に用意されたスクリプトで、言語として Python を使用します。
他に Script-Fu もあります。ここでは、Python-Fu についてのみ説明します。

Python-Fu 用のプログラムを実行するには、GIMPPython-Fu コンソールを使う方法があります。
ここでは、PYthon-Fu コンソールを使わず、バッチとして使う方法を紹介します。

◇手続型データベース(PDB

GIMP を起動して手動で操作する時に呼び出すメニューに該当する関数を Python-Fu スクリプトで呼び出すことができます。
この呼び出し可能な関数をまとめたものを手続き型データベース(PDB)と読んでいます。
Python-Fu の場合、手続き型データベースはオブジェクト gimp.pdb によって表されます。
便宜上 gimp.pdbpdb に割り当てられています。(pdb で参照できます)

◇プロシージャーブラウザー

手続型データベースに登録されたプロシージャ―(関数)に関する情報は、プロシージャ―ブラウザ―で確認できます。
起動した GIMP のメニューから呼び出します。

【起動】 GIMP のメニュー ⇒ ヘルプ ⇒ プロシージャーブラウザー

ここで記述されている関数を Python-Fu で使う場合、次のような記述上の注意が必要です。

  • -_ に変える
  • -1None に変える
  • パラメーターの run-mode は記述しない
  • パラメーターの drawables は、レイヤー、レイヤーマスク、選択範囲などデータを含む構造のオブジェクトを指定

【呼び方】pdb.プロシージャ―名()   ※プロシージャ―ブラウザーにあるものを呼び出すとき

▽プロシージャ―ブラウザ―画面

◎記述サンプル

  • レイヤーに画像を読み込む
    • 構文 :gimp-file-load-layer(run-mode, image, filename) -> layer
    • コード:layer = pdb.gimp_file_load_layer(img, _filename)
  • レイヤーのエクスポート(ファイルに保存)
    • 構文 :gimp-file-save(run-mode, image, drawable, filename, raw-filename)
    • コード:pdb.gimp_file_save(img, layer, out_f_name, "")

◇関数の探し方

関数は、プロシージャーブラウザーの検索機能を使って探します。

検索対象に、「名前で」、「説明で」、「ヘルプで」などを指定できます。

検索には正規表現が使えます。

ただし、英語で検索することになります。

※例えば、拡大するは expand、縮小するは shrink、拡大縮小するは scale ですが、プロシージャーブラウザーでは scale が一番ヒットします。上手く見つからない場合、単語を変えると見つかるかもしれません。

スクリプトファイルに必要なこと

Python-Fu スクリプトは、Python のバージョン2を使用しています。
日本語を扱う場合、次のような注意が必要です。
また、パッケージのインポートも必要です。

  • ファイル内の記述
    • #!/usr/bin/env python
      Linux 環境で必要な Shebang (環境によって必須なのかどうか理解していませんが記述しています)
    • # -*- coding: utf-8 -*-
      日本語を扱う場合は指定します
    • from gimpfu import *
      インポート。これにより、gimpfu, gimp, gimpenumsモジュールがインポートされます
  • ファイルの形式
    • UTF-8 形式で保存
      日本語を扱う場合、ファイル内の coding の記述と併せて設定します

GIMPPython-Fuスクリプトをコマンドライから起動する

GIMP は、コマンドラインオプションで、動作させる Python-Fu スクリプトファイルを指定して動かすことができます。

ここでは、作成した Python-Fu スクリプトファイルを標準入力としてリダイレクトして使用する方法を説明します。

先にサンプルをご覧ください。

◇サンプルスクリプト

以下は、サンプルスクリプトです。
このスクリプトは、コンソール(バッチの場合バッチのコンソール)にメッセージを表示するだけのスクリプトです。

※使い始めはスクリプトがきちんと動いているのかどうか確かめる方法が良くわかりません。
 こちらのスクリプトでその辺りの確認をしていただけます。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from gimpfu import *

# Python-fuスクリプトのコンソールにメッセージを出す
pdb.gimp_message("My Python-fu start")
pdb.gimp_message("Pythonスクリプト実行開始")

◇サンプルバッチ

上記のスクリプトと同じフォルダに置いて使用するバッチファイルです。
ここではスクリプトファイル名を fu_simple_test.py としています。

rem python-fuのファイルをバッチで実行する

setlocal
rem shori:起動方法(1:通常起動、2:コンソール起動)
set shori=2
rem 通常起動用exeの指定
set gimp1="C:\Program Files\GIMP 2\bin\gimp-2.10.exe"
rem コンソール起動用exeの指定
set gimp2="C:\Program Files\GIMP 2\bin\gimp-console-2.10.exe"
rem バッチの存在フォルダ:%~dp0 末尾に\が付く
rem 本ファイルと同じフォルダにあるPythonスクリプトファイルの指定
set scriptpath="%~dp0fu_simple_test.py"

rem 通常起動
if %shori%==1 (
%gimp1% -n -c -d -s -f --batch-interpreter=python-fu-eval -b - -b "pdb.gimp_quit(1)" < %scriptpath%
goto :end
)

rem コンソール起動
if %shori%==2 (
%gimp2% -i -n -c -d -s -f --batch-interpreter=python-fu-eval -b - -b "pdb.gimp_quit(1)" < %scriptpath%
goto :end
)

:end
endlocal
pause
exit

端的には、%gimp1%%gimp2% の行のどちらかだけで動作します。
もちろん、変数は値に置き換えます。

以下にいくつかのポイントを説明します。

◇通常起動とコンソール起動

Python-Fu スクリプトで自動化を図る時、開発中は GIMP の動作が見えると良いかもしれません。
開発が完了して使用する時は、GIMP の起動が見えずに処理が終了すると使い易いです。
上記のサンプルバッチは、通常起動とコンソール起動を切り替えられるようにしています。

GIMP には通常起動用の exe と GIMP の起動が見えないコンソール起動用の exe があります。

  • 通常起動用
    • gimp-2.10.exe
    • -i オプションの指定不可
    • PDB にある Display 系の関数を使用可
  • コンソール起動用
    • gimp-console-2.10.exe
    • -i オプションの指定可
    • PDB にある Display 系の関数を使用しない(エラーになります)

※exe の場所はインストール環境によって異なる可能性があります。
※上記の exe はGIMP バージョン 2.10.18 で Windows 環境の場合です。

◇標準入力からスクリプトファイルを読む

-b または --batch オプションを使用するとスクリプトファイルを指定できます。
この時、値として - を指定するとコマンドを標準入力から読みます。

Windows の場合、ファイルをリダイレクトするとファイルの内容を標準入力して与えられます。
したがって、次のようなオプションでスクリプトファイルのコマンドを実行することができます。

-b - < file-name

◇指定しているオプション

  • 起動を早くするために次のオプションを指定しています。

    -d, -s, -f

  • 既に GIMP を起動していても影響させないように新しいインスタンスで起動するように指定しています。

    -n

  • スクリプトの実行が終わった後に GIMP が閉じるように指定しています。

    -b 'pdb.gimp_quit(1)'

オプションの説明、その他のオプションについては以下を参照してください。

GIMP コマンドラインオプション

  • -i, --no--interfaceユーザーインターフェースなしで起動
  • -c, --console-messages:警告をコンソールに出力(ダイアログに表示しない)
  • -d, --nodata:パターン、各種ブラシなどのデータを読み込まずに起動
  • -s, --no-splash:起動時のスプラッシュスクリーンを非表示
  • --batch-interpreter=<proc>:バッチコマンドを実行するプロシージャ―を指定
    • plug-in-script-fu-eval:Script-Fuを使用(デフォルト)
    • python-fu-evalPython-Fuを使用(Python-Fu を使用する場合は必須
  • -b, --batch=<commands>:一連のコマンドを実行。複数指定可
    <commands> の指定方法
    • スクリプト:直接スクリプトを指定できます
    • スクリプトファイル:ファイルを指定する場合、制限がいろいろあります
    • - :標準入力を読む。リダイレクトでスクリプトファイルを指定して使うと良い
      -b - < スクリプトファイルパス とするとファイルの内容を実行
  • --verbose:起動過程での詳細報告を表示
  • -f, --no-font:フォントを読み込まない
  • -n, --new-instance:重ねて新たにGIMPを起動
  • --stack-trace-mode=mode:クラッシュする原因を調べるためのデバッグ (never|query|always)。
  • --debug-handlers:致命的でないデバッグ用シグナルハンドラーを有効にします。 GIMPデバッグ作業のためのもの
  • --g-fatal-warnings:すべての警告を致命的にする

◇標準入力を使わないでスクリプトファイルを実行

参考(興味があればクリックしてください) 標準入力を使わないでスクリプトファイルをコマンドラインで指定するには、スクリプトファイルをプラグインフォルダに保存して、バッチオプションを次のようにします。

--batch "(python-fu-fu-simple-test RUN-NONINTERACTIVE)"

◎ポイント

  1. スクリプト.py を作成
    register()メソッドの定義が必要
  2. GIMP の plug-ins フォルダに保存
    (スクリプトとして登録したものを起動)

  • 関数名の前に接頭語「python-fu-」を付ける
  • 関数名の「_」は「-」に置き換える
  • RUN-NONINTERACTIVE 引数を指定する

※動作確認はしていません。ご容赦ください。

◆サンプルスクリプトの実行結果

次の画面を見るとプラグインの出力があります。
これは、プラグイン用フォルダーにあるプラグインが動いている(多分インストール)ようです。
 (どう動いているのか、影響があるのか、詳しいことは調べていません)

私の環境には矢印を描画するプラグインが入れてあります。

▽通常起動のバッチ画面

GIMP が起動すると出るコンソール画面

▽コンソール起動のバッチ画面

デバッグについて

コマンドラインオプションの --verbose は、GIMP が起動するまでの情報を表示します。
したがって、デバッグしたいスクリプトの情報は出ません。

いろいろ試した結果、サンプルスクリプトで使用したように pdb.gimp_message() 関数でデバッグ情報を出力するのが良いと判断しています。

エラーがあった場合、次のようが出力があります。

▽文法的なエラーの場合

エラー内容は出ず、スクリプトがエラー終了した表示だけ出ます。

▽関数名を間違えた時のエラー

◆pywinautoでの制御について

はじめは pywinauto を使用して GIMP を制御しようとしました。

アプリケーションのウィンドウは認識できるのですが、中のコントロールを認識できませんでした。
最大化とか最小化とかウィンドウについているメニューしか認識できませんでした。
また、ダイアログなどはWin32で動いているようで、backend を win32 にして調査しました。

スクリプトが提供されているのに RPA でもないかもしれませんが、GIMP の作りが複雑なんだと推測しました。

◆さいごに

GIMPPython 系のスクリプト Python-Fu の動かし方を紹介しました。

標準入力からスクリプトファイルを読み込むと、スクリプトファイルを配布する場合に指定フォルダにコピーしていただかなくても動作するので、配布したいものを作る場合、良い選択だと思います。


あわせて読みたい 📖 コラージュ処理をPython-Fuスクリプトでバッチ処理【GIMP】 🔗:実際に作成したスクリプト
📖 pywinautoでRPA(自動化)◇導入編【Python】 🔗

◇ご注意

本記事は次のバージョンの下で動作した内容を基に記述しています。

◇免責事項

ご利用に際しては、『免責事項』をご確認ください。
お気づきの点がございましたら『お問い合わせ』からお問い合わせください。

◆参考

投稿: 、更新: