[Godot4.3]画像ファイルをドラッグアンドドロップで表示したい

シーン構成とベーススクリプト

シーンはシンプルに

  • root[node2D](root.gd)
  • canvas[CanvasLayer]
    • view[TextureRect]

こんな感じで

# root.gd
extends Node2D

@onready var view:TextureRect = $canvas/view

func _ready() -> void:
	get_window().files_dropped.connect(_on_files_dropped)

func _on_files_dropped(files) -> void:
	for f:String in files:
		print(f)

これでファイルドロップを受け取れる。
ノードがメインウィンドウ内にある場合はget_tree().get_root()と同等らしい。

実行してファイルをドロップ、コンソールにファイルのアドレスが表示されたら成功。

ファイルが画像ファイルかどうか

_on_files_dropped()にはドロップされた1つ以上のファイルパス(文字列)がPackedStringArrayで渡ってくる。
当然、画像ファイル以外もドロップできるので検証は自前でする。

調べた限りでは厳密に画像ファイルかどうかをチェックする方法が見当たらなかった。
もちろん、バイナリで読み込んでヘッダーを見てとかすれば出来るけど。けどもって話。

今回は拡張子のチェックと読み込んでみて読み込めなかったらスキップという方法を採用する。

# root.gd
extends Node2D

@onready var view:TextureRect = $canvas/view

func _ready() -> void:
	get_window().files_dropped.connect(_on_files_dropped)

func _on_files_dropped(files) -> void:
	for f:String in files:
		var f_low = f.to_lower()
		
		if (f_low.ends_with('.jpg') or f_low.ends_with('.jpeg') or f_low.ends_with('.jiff') or
				f_low.ends_with('.png') or f_low.ends_with('.webp')):

			var img:Image = Image.load_from_file(f)

			if img != null:
				if view.texture == null:
					var tex:ImageTexture = ImageTexture.create_from_image(img)
					view.texture = tex
				else:
					view.texture.set_image(img)
				return

画像をドロップして表示されたら成功。

正直、拡張子のチェックは無くてもいい気がする。今回は「jpeg」「png」「webp」に限ったがGodotはもっと読み込める画像フォーマットがあるのでもったいないことになってる。
どっちみち拡張子が合っていても不適切なファイルであればImage.load_from_file(f)nullが返るし。ちなみにその場合はデバッグコンソールに赤文字で怒られる。どうにかしてほしい。

ともあれ、これでファイルドロップで画像を開いて表示できた。
ファイルドロップはゲーム制作ではそうそう使うことって無いと思うけど、ツールやアプリ制作なら必須だよね。

おまけ

Godotに例外処理は無い。「どんなエラーが出てもアプリは落ちてはいけない」という思想らいしい、思想ならしょうがない。

更新履歴

  • 画像を読み込む毎にテクスチャを作っていたので更新するように変更

参考リンク

Node.get_window()

Godot Supported image formats

コメント

タイトルとURLをコピーしました