Python - tkinter で画像のサイズを変更できない

okwaves2024-01-25  8

tkinter ウィンドウ上のフォルダーからループしている画像がいくつかあります。ただし、各画像のサイズは異なるため、コード自体でサイズを変更することはできません。

import tkinter as tk
import glob
root = tk.Tk()
root.geometry('600x600')

pics = glob.glob("./Images/*.png")
photos = [tk.PhotoImage.resize(20,20)(file=x) for x in pics]
label = tk.Label()
label.photos = photos
label.counter = 0
def cimage():
    label['image'] = label.photos[label.counter%len(label.photos)]
    label.after(3000, cimage)
    label.counter += 1
label.pack()
cimage()

root.mainloop()

バージョン 2: 以下も試しましたが、同じエラーが発生しました:

import tkinter as tk
import glob
from PIL import Image, ImageTk
root = tk.Tk()
root.geometry('600x600')

pics = glob.glob("./Images/*.png")
photos=pics.resize((20,20),Image.ANTIALIAS)
photosresized = [tk.PhotoImage(file=x) for x in photos]
label = tk.Label()
label.photosresized = photosresized
label.counter = 0
def changeimage():
    label['image'] = label.photosresized[label.counter%len(label.photosresized)]
    label.after(3000, changeimage)
    label.counter += 1
label.pack()
changeimage()

root.mainloop()

トレースバック:

Traceback (most recent call last):
  File "/Users/ad/Documents/Python/Project_tkinter/test1.py", line 85, in <module>
    photos = [tk.PhotoImage.resize(20,20)(file=x) for x in pics]
  File "/Users/ad/Documents/Python/Project_tkinter/test1.py", line 85, in <listcomp>
    photos = [tk.PhotoImage.resize(20,20)(file=x) for x in pics]
AttributeError: type object 'PhotoImage' has no attribute 'resize'

2 番目のバージョンのトレースバック:

Traceback (most recent call last):
  File "/Users/ad/Documents/Python/Project_tkinter/test1.py", line 86, 
in <module>
    photos=pics.resize((20,20),Image.ANTIALIAS)
AttributeError: 'list' object has no attribute 'resize'

皆さん、ありがとうございました!

以下は、サイズ変更中にアスペクト比を維持するために Joel Toutloff のコードに加えた変更です。

basewidth = 20
for i in pics:
    single_image = Image.open(i)
    wpercent = (basewidth / float(single_image.size[0]))
    hsize = int((float(single_image.size[1]) * float(wpercent)))
    changed_size = single_image.resize((basewidth,hsize),Image.ANTIALIAS)
    pid = ImageTk.PhotoImage(single_image.resize((basewidth,hsize),Image.ANTIALIAS))
    photosresized.append(pid)

1

これであなたの質問は解決しましたか?フォトイマグこのインスタンスには属性「resize」がありません。

– カルティク

2020 年 9 月 3 日 17:25

@Karthik 提供したリンクの例を試してみました。私の投稿で上記のコードを確認してください。エラーが発生しました: AttributeError: 'list'オブジェクトには属性「resize」がありません。

– アドヴィク

2020 年 9 月 3 日 17:52

これは正当なエラーです。写真はリストであり、リストのサイズを変更することはできません。ただし、コンテンツ、つまりリスト内の画像のサイズを変更する必要があります。 for ループ

– カルティク

2020 年 9 月 3 日 17:54



------------------------

glob.glob はファイル名のリストを提供するため、「pics[0]」などでアクセスする必要がありますが、これもファイル名を提供するだけで、実際の画像は提供しません。 画像を再生するには、実際に画像をアクティブ メモリにロードする必要があります。

import tkinter as tk
import glob
from PIL import Image, ImageTk
root = tk.Tk()
root.geometry('600x600')

pics = glob.glob("./Images/*.png")
photosresized = []
for i in pics:
    single_image = Image.open(i)
    changed_size = single_image.resize((20,20),Image.ANTIALIAS)
    pid = ImageTk.PhotoImage(single_image.resize((20,20),Image.ANTIALIAS))
    photosresized.append(pid)
label = tk.Label()
label.photosresized = photosresized
label.counter = 0
def changeimage():
    label['image'] = label.photosresized[label.counter%len(label.photosresized)]
    label.after(3000, changeimage)
    label.counter += 1
label.pack()
changeimage()

root.mainloop()

これは実際の動作を変更しませんl ファイルを任意の方法で作成します。 「Image.open」を使用して、一度に 1 つずつロードします。次に、サイズを変更して、アニメーションで使用するために「photosresize」リストに保存します。

また、PIL で使用する方が好ましいため、tk.PhotoImage を ImageTk.PhotoImage に変更したことにも注意してください。

3

素晴らしい!ありがとう。既存の幅を変更せずに、写真の高さだけを変更する方法はありますか?

– アドヴィク

2020 年 9 月 3 日 18:11

1

画像を取得したら (「single_image」を取得した場合と同様)、.size を使用して幅と高さのタプルを取得できます。したがって、width, height = single_image.size のようなものを使用すると、幅を変数として取得し、それをサイズ変更行で使用できます。

– ジョエル・トートロフ

2020 年 9 月 3 日 19:13

わかりました!変更を加えて元の投稿を更新しました。ありがとう!

– アドヴィク

2020 年 9 月 3 日 19:16



------------------------

画像のサイズを変更するには、PIL.Image.resize() 関数を使用する必要があります。

import glob
import tkinter as tk
from PIL import Image, ImageTk

root = tk.Tk()
root.geometry('600x600')

label = tk.Label()
label.pack()

label.counter = 0

pics = glob.glob("./Images/*.png")
label.photosresized = [ImageTk.PhotoImage(Image.open(x).resize((20,20),Image.ANTIALIAS)) for x in pics]

def changeimage():
    label['image'] = label.photosresized[label.counter%len(label.photosresized)]
    label.counter += 1
    label.after(3000, changeimage)

changeimage()

root.mainloop()

総合生活情報サイト - OKWAVES
総合生活情報サイト - OKWAVES
生活総合情報サイトokwaves(オールアバウト)。その道のプロ(専門家)が、日常生活をより豊かに快適にするノウハウから業界の最新動向、読み物コラムまで、多彩なコンテンツを発信。