mieki256's diary



2025/12/09(火) [n年前の日記]

#1 [gimp][python] GIMP 2.10 + Python-FuでWindowsのファイル選択ダイアログを表示

_先日、 GIMP 3.0 + Python-Fu でWindowsのファイル選択ダイアログを表示できるか実験していたけれど、GIMP 2.10 で同じことができるのか、動作は違ってくるのか気になったので試してみた。

環境は Windows11 x64 25H2 + GIMP 2.10.38 Portable。

ソース :

以下のようなソースになった。

_m256_winopen_gimp2.py
"""
Windowsのファイル選択ダイアログから画像を開くPython-Fuプラグイン
ファイル > Win Open にメニュー項目が追加される。
GIMP 2.10用。

Author : mieki256

Windows11 x64 25H2 + GIMP 2.10.38 Portable
"""

from gimpfu import *
import ctypes
import os

WINOPEN_FILTERS = [
    "All files {*.*}",
    "*.*",
    "PNG",
    "*.png",
    "JPEG",
    "*.jpg;*.jpeg",
]

OFN_ALLOWMULTISELECT = 0x00000200
OFN_FILEMUSTEXIST = 0x00001000
OFN_PATHMUSTEXIST = 0x00000800
OFN_EXPLORER = 0x00080000

BUFFER_SIZE = 32768


class OPENFILENAME_WINDLG(ctypes.Structure):
    """Windowsの標準ファイルダイアログ用の構造体を定義"""

    _fields_ = [
        ("lStructSize", ctypes.c_uint32),
        ("hwndOwner", ctypes.c_void_p),
        ("hInstance", ctypes.c_void_p),
        ("lpstrFilter", ctypes.c_wchar_p),
        ("lpstrCustomFilter", ctypes.c_wchar_p),
        ("nMaxCustFilter", ctypes.c_uint32),
        ("nFilterIndex", ctypes.c_uint32),
        ("lpstrFile", ctypes.c_wchar_p),
        ("nMaxFile", ctypes.c_uint32),
        ("lpstrFileTitle", ctypes.c_wchar_p),
        ("nMaxFileTitle", ctypes.c_uint32),
        ("lpstrInitialDir", ctypes.c_wchar_p),
        ("lpstrTitle", ctypes.c_wchar_p),
        ("Flags", ctypes.c_uint32),
        ("nFileOffset", ctypes.c_uint16),
        ("nFileExtension", ctypes.c_uint16),
        ("lpstrDefExt", ctypes.c_wchar_p),
        ("lCustData", ctypes.c_void_p),
        ("lpfnHook", ctypes.c_void_p),
        ("lpTemplateName", ctypes.c_wchar_p),
        ("pvReserved", ctypes.c_void_p),
        ("dwReserved", ctypes.c_uint32),
        ("FlagsEx", ctypes.c_uint32),
    ]


def get_openfilename_windlg(initial_dir=None, filters=None):
    """Windowsの標準ファイルダイアログを使って複数ファイルを選択"""

    comdlg32 = ctypes.WinDLL("comdlg32")
    comdlg32.GetOpenFileNameW.restype = ctypes.c_bool
    comdlg32.GetOpenFileNameW.argtypes = (ctypes.POINTER(OPENFILENAME_WINDLG),)

    ofn = OPENFILENAME_WINDLG()
    lenFilenameBufferInChars = BUFFER_SIZE
    buf = ctypes.create_unicode_buffer(lenFilenameBufferInChars)

    ofn.lStructSize = ctypes.sizeof(OPENFILENAME_WINDLG)

    # ファイル種類を設定
    if filters:
        ofn.lpstrFilter = "\0".join(filters) + "\0\0"
    else:
        ofn.lpstrFilter = "All files {*.*}\0*.*\0\0"

    if initial_dir:
        ofn.lpstrInitialDir = initial_dir

    ofn.lpstrFile = ctypes.cast(buf, ctypes.c_wchar_p)
    ofn.nMaxFile = lenFilenameBufferInChars
    ofn.lpstrTitle = "Select file"
    ofn.Flags = (
        OFN_ALLOWMULTISELECT | OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST
    )

    # ファイル選択ダイアログを開く
    ret = comdlg32.GetOpenFileNameW(ofn)
    if ret:
        # "\0" を区切り文字とした文字列が得られるので分割してリストにする
        s = buf[:].rstrip("\0")
        path = s[: ofn.nFileOffset].rstrip("\0")
        filenames = s[ofn.nFileOffset :].split("\0")
        files = [os.path.abspath(os.path.join(path, f)) for f in filenames]

        # ファイルパスをリストで返す
        return files

    return []


def python_fu_plugin_m256_win_open():
    """Windowsのファイル選択ダイアログを経由して複数画像ファイルを開く"""

    # 画像を開いてない状態でも動作させるので関数に渡す引数は無い

    initdir = os.path.expanduser("~")
    files = get_openfilename_windlg(initial_dir=initdir, filters=WINOPEN_FILTERS)
    if files:
        # ファイルが選択された

        for filepath in files:
            # "\\" は問題があるらしいので "/" に置換
            path = filepath.replace(os.sep, "/")

            # 画像を読み込む
            image = pdb.gimp_file_load(path, path)
            if image:
                gimp.Display(image)  # GIMPウインドウに画像を表示する
                pdb.gimp_image_clean_all(image)  # 編集中フラグをクリア
            else:
                gimp.message("Image loading failed. [%s]" % (path))
    else:
        # キャンセルされた
        pass

    gimp.displays_flush()


# GIMPプラグインの情報を指定
register(
    "python-fu-m256-win-open",  # プロシージャ名
    "Open Windows file select dialog",  # 簡易説明
    "Open image with Windows file select dialog",  # 詳細説明
    "mieki256",  # 作者名 Author
    "mieki256",  # 著作権者名 Copyright
    "2025/12/07",  # 作成日
    # メニューの表示場所に Toolbox を指定、かつ、画像種類を "" にすることで、
    # 画像を開いていなくても利用できるようにするらしい。
    "Win Open",  # メニューラベル名
    "",  # 画像種類
    [],  # 引数
    [],  # 返り値
    python_fu_plugin_m256_win_open,  # 関数名
    menu="<Toolbox>/File",  # メニューの表示場所
)

main()

  • GIMPのプラグインフォルダにコピーしてからGIMPを実行すると、ファイル → Win Open という項目が増える。
  • Win Open を選ぶと、Windowsのファイル選択ダイアログが開く。複数ファイルの選択も可能。
  • Windowsのショートカットファイル(.lnk)も辿れる。

GIMP 3.0 の場合は、開いた画像の画像バッファ名が「名称未設定」(untitled)になってしまったけれど、GIMP 2.10 の場合はバッファ名に画像ファイル名が反映されていた。やはり以下の動作は違うらしいなと…。GIMP 3.0 の動作はバグなのか、それとも仕様なのか…。

            # GIMP2.10
            # 画像を読み込む
            image = pdb.gimp_file_load(path, path)

        # GIMP 3.0
        # 画像を読み込む
        file = Gio.File.new_for_path(filepath_unix)
        image = Gimp.file_load(Gimp.RunMode.NONINTERACTIVE, file)

以上です。

過去ログ表示

Prev - 2025/12 -
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project