質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

2回答

2293閲覧

python: 読み込んだ画像ファイルが表示できません

yyohei

総合スコア1

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/05/10 09:44

編集2020/05/10 15:24

前提・実現したいこと

python 初心者です。

def で作った関数で読み込んだ画像ファイルを表示させようとしているのですが、
ある行の有無で、ファイル表示が左右されます。
下記コードの関数定義 def fileread 中、一番下(11行目)の
lbl.image = imageData が無いと、読み込んだファイルが表示されません。

お二人からご返信頂き考えていたのですが、

まず、lbl は21行目の lbl = tk.Label(image=imageDatac1) で宣言しており、
fileread の外なので、グローバル変数と思っています。

次に fileread の中ですが、lbl という名前を使っている為、
10行目:グローバル変数 lbl の属性 image を imageData に変更する。
11行目:グローバル変数 lbl の属性 image を imageData にする。
のように思ってしまっています。

10行目の fileread 内の lbl.configure(image = imageData) では、
lblという変数を使っていますが、21行目で宣言している lbl には繋がっておらず、
この lbl は fileread 内のローカル変数ということでしょうか?

また、fileread内の lbl がローカル変数とすると、
11行目の lbl.image = imageData があると、何故繋がるのでしょうか?

根本的に理解できておらず申し訳ありませんが、宜しくお願い致します。

発生している問題・エラーメッセージ

 読み込んだ画像が表示されません。

該当のソースコード

python

1import tkinter as tk 2import tkinter.filedialog as fd 3import PIL.Image 4import PIL.ImageTk 5 6def fileread(): 7 fpath = fd.askopenfilename() 8 newImage = PIL.Image.open(fpath).resize((300,300)) 9 imageData = PIL.ImageTk.PhotoImage(newImage) 10 lbl.configure(image = imageData) ### <- lbl はローカル変数でしょうか? 11 lbl.image = imageData ### <- lbl はグローバル変数でしょうか? 12 13root = tk.Tk() 14root.title("select dog, cat") 15root.geometry("400x350") 16 17btn = tk.Button(text="画像を選ぶ", command = fileread) 18 19newImagec1 = PIL.Image.open("img\cat1.png").resize((300,300)) 20imageDatac1 = PIL.ImageTk.PhotoImage(newImagec1) 21lbl = tk.Label(image=imageDatac1) 22 23newImaged1 = PIL.Image.open("img\dog1.jpg").resize((400,300)) 24imageDatad1 = PIL.ImageTk.PhotoImage(newImaged1) 25lbl.configure(image = imageDatad1) 26lbl.image = imageDatad1 ### <- あっても無くても動く。 27 28lbl.pack() 29btn.pack() 30 31tk.mainloop() 32

試したこと

def の外で、同様の文を書いてみましたが、そちらは画像表示に影響しませんでした。
(上記コード中、26行目)

補足情報(FW/ツールのバージョンなど)

python 3.8.2

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

teamikl

2020/05/10 10:08

関数filereadの範囲はroot前迄ですか? 出来ればmarkdownを使ってコード整形をお願いします。
yyohei

2020/05/10 15:25

失礼致しました。code 整形しました。
guest

回答2

0

関数内のローカル変数は、ガベージコレクタにより回収されて消えてしまう為です。

関数内の場合(ローカル変数)

python

1def fileread(): 2 fpath = fd.askopenfilename() 3 newImage = PIL.Image.open(fpath).resize((300,300)) 4 imageData = PIL.ImageTk.PhotoImage(newImage) 5 lbl.configure(image = imageData) 6 lbl.image = imageData ### <- 何故必要なのでしょうか? 7 8 # 関数の実行が終わった後 変数imageData がなくなる為。 9 # lbl.image に参照を残すことで、読み込んだ画像が消えてしまうのを回避しています。 10 # (lblはグローバル変数と仮定します)

グローバル変数の場合

python

1newImaged1 = PIL.Image.open("img\dog1.jpg").resize((400,300)) 2imageDatad1 = PIL.ImageTk.PhotoImage(newImaged1) 3lbl.configure(image = imageDatad1) 4lbl.image = imageDatad1 ### <- あっても無くても動く。 5 6# グローバル変数の寿命はプログラムが動いている間ずっとなので、この位置ではなくても動きます。

投稿2020/05/10 10:16

teamikl

総合スコア8664

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yyohei

2020/05/10 13:20

早速のご回答ありがとうございます。 fileread の範囲は root の前までです。コピペしたとき、段落が消えてしまってました。
guest

0

関数内の imageData 変数は、関数内のローカル変数で、関数を終了すると変数が破棄されて、読み込んだ画像データも消滅します。
関数外で変数に代入た場合はグローバル変数で、プログラムが終了するまで変数もデータも残っているので表示できます。

PIL.ImageTk.PhotoImage(newImage) の中でデータをコピーしていれば問題ないのですが、PhotoImageはC言語で実装されたプログラムで、Python側の変数との連携がうまく実装されていないのだと思います。

投稿2020/05/10 10:03

編集2020/05/10 10:05
shiracamus

総合スコア5406

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yyohei

2020/05/10 13:04

早速のご回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問