シーン構成とベーススクリプト
シーンはシンプルに
- 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に例外処理は無い。「どんなエラーが出てもアプリは落ちてはいけない」という思想らいしい、思想ならしょうがない。
更新履歴
- 画像を読み込む毎にテクスチャを作っていたので更新するように変更
コメント