Search on blog:

Tkinter: Jak wyświetlać obrazy

Przykładowe obrazki

Na początek kilka obrazków, które używam w przykładach. Mogą być ona przydatne przy testowaniu przykładów.

python przykładowy obrazek do wyświetlania w tkinter 1 python przykładowy obrazek do wyświetlania w tkinter 2 python przykładowy obrazek do wyświetlania w tkinter 3

Wczytanie obrazka z tkinter.PhotoImage()

Tkinter używa PhotoImage do wczytania PNG, GIF lub PGM/PPM ale nie potrafi on wczytać JPG lub innego formatu. Starsze wersje nie potrafiły wczytać nawet PNG.

import tkinter as tk

root = tk.Tk()

img = tk.PhotoImage(file="smile-1.png")

# ... TODO: display image ...

root.mainloop()

tkinter.PhotoImage musi być stworzony po tk.Tk(), który inicjuje pewne elementy potrzebne do wczytania obrazka.

tkinter.PhotoImage wymaga użycia nazwanej zmiennej file=. Jeśli się pominie tą nazwę zmiennej to wtedy próbuje on użyć nazwy pliku ze zmienną data=, która oczekuje obrazka w postaci tekstu zakodowanego z base64. Więcej o base64 string w innym poscie.

Aby wczytać JPG lub inny format trzeba użyć moduły pillow. Więcej o tym na końcu tej strony.


Wyświetlanie obrazka z użyciem Label

Tkinter może pokazać PhotoImage używając Label

import tkinter as tk

root = tk.Tk()

img = tk.PhotoImage(file="smile-1.png")

label = tk.Label(root, img)
label.pack()

root.mainloop()

Można także przypisać PhotoImage do już istniejącego Label używając

img = tk.PhotoImage(file="smile-1.png")

label["image"] = img
# or
label.config(image=img)

W ten sam sposób można też zamienić/podmienić obraz bez tworzenia nowego Label. Można to wykonać w funkcji wywołanej przez Button lub inny widżet, lub używając zdarzenia z bind(), lub używając czasu z after().

import tkinter as tk

# --- functions ---

def on_click():
    global current_img  # inform function to assing value to external/global variable

    if current_img == img1:
        current_img = img2
    else:
        current_img = img1

    label["image"] = current_img

# --- main ---

root = tk.Tk()

img1 = tk.PhotoImage(file="smile-1.png")
img2 = tk.PhotoImage(file="smile-2.png")
current_img = img1

label = tk.Label(root, image=current_img)
label.pack()

button = tk.Button(root, text="Change", command=on_click)
button.pack()

root.mainloop()

Używając listy z obrazkami można by stworzyć przeglądarkę obrazków.


Wyświetlanie obrazka z użyciem Button

Tkinter` może pokazać ``PhotoImage używając Button

import tkinter as tk

root = tk.Tk()

img = tk.PhotoImage(file="smile-1.png")

button = tk.Button(root, image=img)
button.pack()

root.mainloop()

Można także przypisać PhotoImage do już istniejącego Button używając

img = tk.PhotoImage(file="smile-1.png")

button["image"] = img
# or
button.config(image=img)

W ten sam sposób można też zamienić/podmienić obraz bez tworzenia nowego Button. Można to wykonać w funkcji wywołanej przez Button lub inny widżet, lub używając zdarzenia z bind(), lub używając czasu z after().

import tkinter as tk

# --- functions ---

def on_click():
    global current_img  # inform function to assing value to external/global variable

    if current_img == img1:
        current_img = img2
    else:
        current_img = img1

    button["image"] = current_img

# --- main ---

root = tk.Tk()

img1 = tk.PhotoImage(file="smile-1.png")
img2 = tk.PhotoImage(file="smile-2.png")
current_img = img1

button = tk.Button(root, image=current_img, command=on_click, compound="top", text="Image")
button.pack()

root.mainloop()

Używając listy z obrazkami można by stworzyć przeglądarkę obrazków.


Wyświetlanie obrazka z użyciem Canvas

Tkinter` może pokazać ``PhotoImage używając Canvas

import tkinter as tk

root = tk.Tk()

img = tk.PhotoImage(file="smile-1.png")

canvas = tk.Canvas(root)
canvas.pack()

img_id = canvas.create_image((0, 0), image=img, anchor='nw')

root.mainloop()

Wymaga on pozycji (x, y) dla obrazka. Pozycja (0, 0) jest w górnym lewym rogu. Domyślnie umieszcza on środek obrazka we wskazanej pozycji ale można to zmienić za pomocą anchor=. Jeśli użyć anchor="nw" (nw = North West = Góra Lewy) to wtedy umieści górny lewy narożnik obrazka w pozycji (x, y)

create_image() dalej id obiektu stworzonego na płótnie i można go użyć z innymi funkcjami do usunięcia, zamiany lub przesunięcia obrazka.

import tkinter as tk
import random

# --- functions ---

def on_click():
    x = random.randint(0, 250)
    y = random.randint(0, 250)
    canvas.moveto(img_id, x, y)

# --- main ---

root = tk.Tk()

img = tk.PhotoImage(file="smile-1.png")

canvas = tk.Canvas(root)
canvas.pack()

img_id = canvas.create_image((0, 0), image=img, anchor='nw')

button = tk.Button(root, text="move", command=on_click)
button.pack()

root.mainloop()

Używając listy z obrazkami można by stworzyć przeglądarkę obrazków.

Używając przycisków i/lub after() można stworzyć animację lub grę.

import tkinter as tk
import random

# --- functions ---

def move_image():
    dx = random.randint(-10, 10)
    dy = random.randint(-10, 10)
    canvas.move(img_id, dx, dy)
    # move image again after 100ms (0.1s)
    root.after(100, move_image)

# --- main ---

root = tk.Tk()

img = tk.PhotoImage(file="smile-1.png")

canvas = tk.Canvas(root)
canvas.pack()

img_id = canvas.create_image((100, 100), image=img)

# move image first time
#root.after(100, move_image)
move_image()

root.mainloop()

Wyświetlanie obrazka i tekstu z użyciem Label lub Button

Kiedy Label lub Button wyświetla obrazek wtedy nie pokazuje tekstu.

Aby wyświetlić tekst i obrazek w tym samym czasie wymage to użycia compound= aby zdefiniować gdzie ma być pokazany obrazek left, right, top, bottom lub center aby pokazać tekst na obrazku.

label = tk.Label(root, text="Image", image=img, compound="top")

button = tk.Butoon(root, text="Button", image=img, compound="top")
import tkinter as tk

root = tk.Tk()

img = tk.PhotoImage(file="smile-1.png")

label = tk.Label(root, image=img, text='Hello')
label.pack()

label = tk.Label(root, image=img, text='left', compound='left')
label.pack()

label = tk.Label(root, image=img, text='right', compound='right')
label.pack()

label = tk.Label(root, image=img, text='top', compound='top')
label.pack()

label = tk.Label(root, image=img, text='bottom', compound='bottom')
label.pack()

label = tk.Label(root, image=img, text='center', compound='center', fg='red')
label.pack()

root.mainloop()
tkinter wyświetlanie obrazka z tekstem na label lub button

Wczytanie obrazka z ImageTk.PhotoImage()

Aby wczytać JPG lub innym format trzeba użyć ImageTk.PhotoImage() z modułu pillow. Oczywiście można go użyć także do wczytania PNG, GIF.

import tkinter as tk
from PIL import ImageTk

root = tk.Tk()

img = ImageTk.PhotoImage(file="smile-1.png")

label = tk.Label(root, image=img)
label.pack()

root.mainloop()

ImageTk.PhotoImage musi być stworzony po tk.Tk(), który inicjuje pewne elementy potrzebne do wczytania obrazka.

ImageTk.PhotoImage wymaga użycia nazwanej zmiennej file= aby wczytać bezpośrednio z pliku. If you skip this name then it tries to use with data= which needs pillow.Image which can be very useful.

Jeśli się pominie tą nazwę zmiennej to wtedy próbuje on użyć nazwy pliku ze zmienną data=, która oczekuje obrazka pillow.Image, który może być bardzo użyteczny. pillow ma funkcje do zmieniania wielkości, obracania, przycinania, zamiany kolorów, wstawiania jednego obrazka na drugi, a także do rysowania tekstu lub figur (z użyciem ImageDraw)

import tkinter as tk
from PIL import Image, ImageTk

image = Image.open("smile-1.png")
image = image.resize((350, 350)).invert()

root = tk.Tk()

img = ImageTk.PhotoImage(image)

label = tk.Label(root, image=img)
label.pack()

root.mainloop()

Błąd w PhotoImage

PhotoImage posiada się błąd, który powoduje usunięcie obrazka z pamięci (a co za tym idzie wyświetla puste miejsce) jeśli obraz został przypisany do lokalnej zmiennej stworzonej w funkcji lub w metodzie klasy.

PhotoImage musi zostać przypisany do zmiennej globalnej

def function():
    global img

    img = tk.PhotoImage(file="smile-1.png")

lub do dowolnej zmiennej w istniejącym obiekcie

def function():
    img = tk.PhotoImage(file="smile-1.png")

    label = tk.Label(image=img)
    label.image = img  # it can be different name - ie. `label.img`

    label.pack()

lub z użyciem self. w klasie

class MyWindow:

    def method(self):
        self.img = tk.PhotoImage(file="smile-1.png")

Linki:

  • [web.archive.org] effbot.org: PhotoImage
  • [web.archive.org] effbot.org: Label
  • [web.archive.org] effbot.org: Button
  • [web.archive.org] effbot.org: Canvas
If you like it
Buy a Coffee