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。
環境は Windows11 x64 25H2 + GIMP 2.10.38 Portable。
◎ ソース :
以下のようなソースになった。
_m256_winopen_gimp2.py
GIMP 3.0 の場合は、開いた画像の画像バッファ名が「名称未設定」(untitled)になってしまったけれど、GIMP 2.10 の場合はバッファ名に画像ファイル名が反映されていた。やはり以下の動作は違うらしいなと…。GIMP 3.0 の動作はバグなのか、それとも仕様なのか…。
_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)
[ ツッコむ ]
以上、1 日分です。