stringcraft
stringcraft

Reputation: 105

Struggling to resize an image within Tkinter

I have developed a console-based adventure game for my Sixth Form Computing class, and now want to migrate it into Tkinter. The main reason for this is that I can make use of pictures, mainly ones from game-icons.net.

So far so good, but the images are such high quality that they appear huge when I display them. Here is an example:

Problem with image size

The code works by using a for loop to iterate through a list of items that are in the current area (that the player is in). Here is the code:

if len(itemKeys) > 0:
    l = Label(lookWindow, text="Looking around, you see the following items....\n").pack()
    for x in range(0, len(itemKeys)):
        icon = PhotoImage(file=("icons\\" + itemKeys[x] + ".png"))
        l = Label(lookWindow, image=icon)
        l.photo = icon
        l.pack()
        l = Label(lookWindow, text=("" + itemKeys[x].title())).pack()
        l = Label(lookWindow, text=("   " + locations[position][2][itemKeys[x]][0] + "\n")).pack()

else:
    l = Label(lookWindow, text="There's nothing at this location....").pack()

The part saying ("icons\\" + itemKeys[x] + ".png") simply goes into the icons folder in the game directory and strings together a file name, which in this case would result in "key.png" because the item we're currently looking at is a key.

Now, however, I want to resize the image. I've tried using PIL (which people say is deprecated but I managed to install just fine?) but so far no luck.

Any help appreciated. Jake

EDIT: The question has been marked as a duplicate, but I've already tried to use it, but the person who answered seems to open a file, save it as a ".ppm"(?) file and then display it, but when I try I get a huge error that says that I couldn't display a "PIL.Image.Image".

EDIT 2: Changed it to this:

im_temp = PILImage.open(("icons\\" + itemKeys[x] + ".png")).resize((250,250), PILImage.ANTIALIAS)
photo = PhotoImage(file=im_temp)
label = Label(lookWindow, image=photo)
label.photo = photo
label.pack()

and now get this:

edit 2

Upvotes: 1

Views: 3156

Answers (2)

ChaosPredictor
ChaosPredictor

Reputation: 4051

For python 2 you can do something like this, it should work for python 3 as well after small changes of import

from tkinter import Tk, Label
from PIL import Image, ImageTk

root = Tk()

file = 'plant001.png'

image = Image.open(file)

zoom = 0.5

#multiple image zise by zoom
pixels_x, pixels_y = tuple([int(zoom * x)  for x in image.size])

img = ImageTk.PhotoImage(image.resize((pixels_x, pixels_y))) # the one-liner I used in my app
label = Label(root, image=img)
label.image = img # this feels redundant but the image didn't show up without it in my app
label.pack()

root.mainloop()

Upvotes: 2

Michiel Overtoom
Michiel Overtoom

Reputation: 1619

Instead of resizing those huge images on-the-fly, you could preprocess them before bunding them with your application. I took the 'key' and 'locked chest' images and placed them in a 'icons' subdirectory, then ran this code:

from PIL import Image
import glob

for infn in glob.glob("icons/*.png"):
    if "-small" in infn: continue
    outfn = infn.replace(".png", "-small.png")
    im = Image.open(infn)
    im.thumbnail((50, 50))
    im.save(outfn)

It created a 'key-small.png' and 'locked-chest-small.png', which you can use in your application instead of the original images.

Upvotes: 1

Related Questions