Image resize under PhotoImage

Question:

I need to resize an image, but I want to avoid PIL, since I cannot make it work under OS X – don’t ask me why…

Anyway since I am satisfied with gif/pgm/ppm, the PhotoImage class is ok for me:

photoImg = PhotoImage(file=imgfn)
images.append(photoImg)
text.image_create(INSERT, image=photoImg)

The problem is – how do I resize the image?
The following works only with PIL, which is the non-PIL equivalent?

img = Image.open(imgfn)
img = img.resize((w,h), Image.ANTIALIAS)
photoImg = ImageTk.PhotoImage(img)
images.append(photoImg)
text.image_create(INSERT, image=photoImg) 

Thank you!

Asked By: alessandro

||

Answers:

You have to either use the subsample() or the zoom() methods of the PhotoImage class. For the first option you first have to calculate the scale factors, simply explained in the following lines:

scale_w = new_width/old_width
scale_h = new_height/old_height
photoImg.zoom(scale_w, scale_h)
Answered By: Constantinius

Because both zoom() and subsample() want integer as parameters, I used both.

I had to resize 320×320 image to 250×250, I ended up with

imgpath = '/path/to/img.png'
img = PhotoImage(file=imgpath)
img = img.zoom(25) #with 250, I ended up running out of memory
img = img.subsample(32) #mechanically, here it is adjusted to 32 instead of 320
panel = Label(root, image = img)
Answered By: Memes

I just had the same problem, and I found that @Memes’ answer works rather well. Just make sure to reduce your ratio as much as possible, as subsample() takes a rather long time to run for some reason.

Basically, the image is zoomed out to the least common factor of the two sizes, and then being subsidized by the origonal size. This leaves you with the image of the desired size.

Answered By: Patrick

If you don’t have PIL installed –> install it

(for Python3+ users –> use ‘pip install pillow’ in cmd)

from tkinter import *
import tkinter
import tkinter.messagebox
from PIL import Image
from PIL import ImageTk

master = Tk()
 
def callback():
    print("click!")

width = 50
height = 50
img = Image.open("dir.png")
img = img.resize((width,height), Image.ANTIALIAS)
photoImg =  ImageTk.PhotoImage(img)
b = Button(master,image=photoImg, command=callback, width=50)
b.pack()
mainloop()
Answered By: Vyr

I had a requirement where I wanted to open an image, resize it, keeping the aspect ratio, save it under a new name, & display it in a tkinter window (using Linux Mint). After looking through dozens of forum questions, and dealing with some weird errors (semmingly involving the PIL to Pillow fork in Python 3.x), I was able to develop some code that works, using a predefined new maximum width or new maximum height (scaling up or down as necessary), and a Canvas object, where the image is displayed centered in the frame. Note that I did not include the file dialogs, just a hardcoded Image open & save for one file:

from tkinter import *
from PIL import ImageTk, Image
import shutil,os
from tkinter import filedialog as fd

maxwidth = 600
maxheight = 600

mainwindow = Tk()
picframe = Frame(mainwindow)
picframe.pack()
canvas = Canvas(picframe, width = maxwidth, height = maxheight)  
canvas.pack()

img = Image.open("/home/user1/Pictures/abc.jpg")

width, height = img.size                # Code to scale up or down as necessary to a given max height or width but keeping aspect ratio
if width > height:
    scalingfactor = maxwidth/width
    width = maxwidth
    height = int(height*scalingfactor)
else:
    scalingfactor = maxheight/height
    height = maxheight
    width = int(width*scalingfactor)

img = img.resize((width,height), Image.ANTIALIAS)

img.save("/home/user1/Pictures/Newabc.jpg")

img = ImageTk.PhotoImage(img)     # Has to be after the resize
canvas.create_image(int(maxwidth/2)-int(width/2), int(maxheight/2)-int(height/2), anchor=NW, image=img)   # No autocentering in frame, have to manually calculate with a new x, y coordinate based on a NW anchor (upper left)
Answered By: Aaron Gordon
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.