Skip to content Skip to sidebar Skip to footer

How To Resize An Image To Fit The Label Size? (python)

My aim is to create a random country generator, and the flag of the country that is picked will appear. However, if the image file is bigger than the predetermined size of the labe

Solution 1:

If you don't have PIL installed, first you need to install

pip install pillow

Once installed you can now import from PIL:

fromPILimportImage, ImageTk

Tk's PhotoImage can only display .gif's, whereas PIL's ImageTk will let us display various image formats in tkinter and PIL's Image class has a resize method we can use to resize the image.

I trimmed your code down some.

You can resize the image and then just configure the label, the label will expand to be the size of the image. If you gave the label a specific height and width, lets say height=1 and width=1 and you resized the image to be 500x500 and then configured the widget. It would still display a 1x1 label since you've set these attributes explicitly.

In the below code, modifiying the dict, it is not okay to modify a dict while iterating over it. dict.items() returns a copy of the dict.

There's various ways to do this, I just though a dict was convenient here.

Link to an image that's over the height / width limit - kitty.gif

from tkinter import *
import random
from PIL import Image, ImageTk

WIDTH, HEIGHT = 150, 150
flags = {
    'England': 'england.gif',
    'Wales': 'wales.gif', 
    'Kitty': 'kitty.gif'
}

defbatch_resize():

    for k, v in flags.items():
        v = Image.open(v).resize((WIDTH, HEIGHT), Image.ANTIALIAS)
        flags[k] = ImageTk.PhotoImage(v)

defnewcountry():

    country = random.choice(list(flags.keys()))
    image = flags[country]
    flagLabel['text'] = country
    flagpicture.config(image=image)

if __name__ == '__main__':

    root = Tk()
    root.configure(bg='black')

    batch_resize()

    flagLabel = Label(root, text="", bg='black', fg='cyan', font=('Helvetica',40))
    flagLabel.pack()

    flagpicture = Label(root)
    flagpicture.pack()

    newflagButton = Button(root, text="Next Country", command=newcountry)
    newflagButton.pack()
    root.mainloop()

Solution 2:

Instead of randomly selecting a country to display its flag, we loop through the flags dictionary that is key-sorted. Unlike the random choice which will inevitably repeat the flags, this scheme runs through the countries in alphabetical order. Meanwhile, we resize all the images to a fixed pixel size based on the width and height of the root window multiplied by a scale factor. Below is the code:

import  tkinter as tk
from PIL import Image, ImageTk

classFlags:

    def__init__(self, flags):
        self.flags = flags
        self.keyList = sorted(self.flags.keys()) # sorted(flags)
        self.length = len(self.keyList)
        self.index = 0defresize(self, xy, scale):
        xy = [int(x * y) for (x, y) inzip(xy, scale)]
        for k, v in self.flags.items():
            v = Image.open(r'C:/Users/user/Downloads/' + v)
            v = v.resize((xy[0], xy[1]), Image.ANTIALIAS)
            self.flags[k] = ImageTk.PhotoImage(v)

    defnewCountry(self, lbl_flag, lbl_pic):
        country = self.keyList[self.index]
        lbl_flag["text"] = country
        img = self.flags[country]
        lbl_pic.config(image = img)
        self.index = (self.index + 1) % self.length # loop around the flags dictionarydefrootSize(root):
    # Find the size of the root window
    root.update_idletasks()
    width = int(root.winfo_width() * 1.5)      #   200 * m
    height = int(root.winfo_height() * 1.0)    #   200 * mreturn width, height

defcenterWsize(root, wh):
    root.title("Grids layout manager")
    width, height = wh
    # Find the (x,y) to position it in the center of the screen
    x = int((root.winfo_screenwidth() / 2) - width/2)
    y = int((root.winfo_screenheight() / 2) - height/2)
    root.geometry("{}x{}+{}+{}".format(width, height, x, y))

if __name__ == "__main__":

    flags = {
        "Republic of China": "taiwan_flag.png",
        "United States of America": "america_flag.gif",
        "America": "america_flag.png",
    }

    root = tk.Tk()
    wh = rootSize(root)
    centerWsize(root, wh)
    frame = tk.Frame(root, borderwidth=5, relief=tk.GROOVE)
    frame.grid(column=0, row=0, rowspan=3)
    flag = Flags(flags)
    zoom = (0.7, 0.6)   # Resizing all the flags to a fixed size of wh * zoom
    flag.resize(wh, zoom)
    lbl_flag = tk.Label(frame, text = "Country name here", bg = 'white', fg = 'magenta', font = ('Helvetica', 12), width = 30)
    lbl_flag.grid(column = 0, row = 0)
    pic_flag = tk.Label(frame, text = "Country flag will display here")
    pic_flag.grid(column = 0, row = 1)
    btn_flag = tk.Button(frame, text = "Click for next Country Flag",
                         bg = "white", fg = "green", command = lambda : flag.newCountry(lbl_flag, pic_flag))
    btn_flag.grid(column = 0, row = 2)

    root.mainloop()

Solution 3:

You can use the PIL(pillow module to resize the image)

But in order to resize the images to exactly to the widget size, You can do the following. (Assuming that you are familiar with basic tkinter syntax structure)

your_widget.update() #We are calling the update method in-order to update the #widget size after it's creartion, Other wise, it will just print '1' and '1' #rather than the pixel size.

height=your_widget.winfo_height()
width=your_widget.winfo_width()
print(height,weight)

Now you can use the height and width information to create a new image that you can size it perfectly to your widget.

But if you have your image is already created, you can use the PIL module to resize the image to your size

first open your image with

flag_temp = Image.open("file location")

next resize the image to your size

flag_new = flag_temp.resize((10,10))# example size

make your final image to add in your widget

flag_final = ImageTk.PhotoImage(flag_new)

now you can use the 'flag final' varible in your widget.

IF YOUR APP HAS TO BE RESIZED AT ANY POINT, you can use the height and width varible created in the first code para, to dynamically resize the image But you should make sure that the function is called regularly to update it.

You should also pass in the height and width variable in the place of (10,10) something like this

flag_new = flag_temp.resize((height,widht)

Hopefully this was helpful, I think the answer is bit long for your question, If you have any problems pls comment below.

Post a Comment for "How To Resize An Image To Fit The Label Size? (python)"