drakide
drakide

Reputation: 151

How to resize an image using tkinter?

Is it possible to resize an image using tkinter only? If so, how can that be done?

Upvotes: 14

Views: 49195

Answers (5)

Sean
Sean

Reputation: 79

from PIL import Image

img = Image.open("flower.png")
img = img.resize((34, 26), Image.ANTIALIAS)

For further information, go to http://effbot.org/imagingbook/image.htm (link dead now, here is its archive)

Upvotes: 7

garydavenport73
garydavenport73

Reputation: 479

Here is a way to resize images (PhotoImages) using just tkinter. Here is a simple function that may suit your needs. This is a rudimentary function that reads the image pixel by pixel simply scaling from one image to another. It may be slow, but depending on your needs, it may suit you well. (In this context/discussion when I refer to an image, I am referring to a PhotoImage or instance of PhotoImage.)

Basically, it takes three arguments:

  • your image (an instance of a PhotoImage)
  • your desired width in pixels
  • your desired height in pixels

It returns a new instance of a PhotoImage. If you want, you can reference your original image to the returned image effectively resizing your image. Or you can just retrieve a new image. Here is the function and some examples:

from tkinter import *


def resizeImage(img, newWidth, newHeight):
    oldWidth = img.width()
    oldHeight = img.height()
    newPhotoImage = PhotoImage(width=newWidth, height=newHeight)
    for x in range(newWidth):
        for y in range(newHeight):
            xOld = int(x*oldWidth/newWidth)
            yOld = int(y*oldHeight/newHeight)
            rgb = '#%02x%02x%02x' % img.get(xOld, yOld)
            newPhotoImage.put(rgb, (x, y))
    return newPhotoImage

That function should resize an image, pixel by pixel and return a new image.

Basically in a nutshell, you create an image of the desired size and must fill it in pixel by pixel with your desired colors using data from the original image. You can think of this process maybe using a line (y=mx+b where b=0) or ratio or scale factor or however you want to think about it. Bottom line is you have to fill in the new pixel data by retrieving data from the original image.

To change the size of your image you could do something like this. Here would be example code:

from tkinter import *

#insert the resize function here

root = Tk()

myCanvas = Canvas(root, width=300, height=300)
myCanvas.pack()

puppyImage = PhotoImage(file="bassethound.png")  # a 200px x 200px image
puppyImage = resizeImage(puppyImage, 150, 150)  # resized to 150px x 150px

myCanvas.create_image(50, 50, anchor=NW, image=puppyImage)
myCanvas.create_text(0, 0, anchor=NW, text="original 200x200\nnow150x150")

root.mainloop()

And here is the result: enter image description here

And here is the 200x200 image, shrunk to 100x100 and expanded to 300x300 with this code:

from tkinter import *

#insert the resize function here

root = Tk()

myCanvas = Canvas(root, width=600, height=300)
myCanvas.pack()

puppyImage = PhotoImage(file="bassethound.png")  # a 200px x 200px image
puppySmall = resizeImage(puppyImage, 100, 100)
puppyLarge = resizeImage(puppyImage, 300, 300)

myCanvas.create_image(0, 0, anchor=NW, image=puppyImage)
myCanvas.create_text(0, 0, anchor=NW, text="original 200x200")
myCanvas.create_image(200, 0, anchor=NW, image=puppySmall)
myCanvas.create_text(200, 0, anchor=NW, text="small 100x100")
myCanvas.create_image(300, 0, anchor=NW, image=puppyLarge)
myCanvas.create_text(300, 0, anchor=NW, text="larger 300x300")


root.mainloop()

And here is the result of that code: enter image description here

Here are just some arbitrary numbers, say 273px and 88px:

from tkinter import *

# put resize function here

root = Tk()

myCanvas = Canvas(root, width=400, height=100)
myCanvas.pack()

puppyImage = PhotoImage(file="bassethound.png")  # a 200px x 200px image
puppyImage = resizeImage(puppyImage, 273, 88)  # resized to 273px x 88px

myCanvas.create_image(0, 0, anchor=NW, image=puppyImage)


root.mainloop()

and the result: enter image description here

This answer inspired by acw1668 and roninpawn at the following link: How to rotate an image on a canvas without using PIL?

photo attribution: n nlhyeyyeusysAnderson Nascimento, CC BY 2.0 https://creativecommons.org/licenses/by/2.0, via Wikimedia Commons from: https://en.wikipedia.org/wiki/Puppy

Upvotes: 6

Alex Boxall
Alex Boxall

Reputation: 571

You can resize a PhotoImage using the zoom and subsample methods. Both methods return a new PhotoImage object.

from tkinter import *
root = Tk()     #you must create an instance of Tk() first

image = PhotoImage(file='path/to/image.gif')
larger_image = image.zoom(2, 2)         #create a new image twice as large as the original
smaller_image = image.subsample(2, 2)   #create a new image half as large as the original

However, both of these methods can only take integer values as arguments, so the functionality is limited.

It is possible to scale by decimal values but it is slow and loses quality. The below code demonstrates scaling by 1.5x:

new_image = image.zoom(3, 3)            #this new image is 3x the original
new_image = new_image.subsample(2, 2)   #halve the size, it is now 1.5x the original

Upvotes: 18

user4746908
user4746908

Reputation:

Just in case anyone comes across this for future reference, as I was looking for this myself earlier. You can use tkinter's PhotoImage => subsample method

I wouldn't say it really resizes in a certain sense but if you look up the documentation it returns the same image but skips X amount of pixels specified in the method.

ie:

 import tkinter as tk
 root = tk.Tk()
 canvas = tk.Canvas(root, ....)
 canvas_image = tk.PhotoImage(file = path to some image)
 #Resizing
 canvas_image = canvas_image.subsample(2, 2) #See below for more: 
                                             #Shrinks the image by a factor of 2 effectively

 canvas.create_image(0, 0, image = canvas_image, anchor = "nw")
 self.canvas_image = canvas_image #or however you want to store a refernece so it's not collected as garbage in memory

So say our original image was 400x400 it is now effectively at 200x200. This is what I've been using when I need to compile a game or something I made and don't want to deal with PIL and it's compiling issues.

However, other than the above reason I'd just use PIL.

Upvotes: 5

Noufal Ibrahim
Noufal Ibrahim

Reputation: 72745

As far as I know (and it's been a while since I've touched Tkinter), it's a GUI toolkit. The closest it comes to "images" is the PhotoImage class which allows you to load them up and use them in your GUIs. If you want to edit/alter an image, I think you'd be better of using the Python imaging library (PIL).

Upvotes: 1

Related Questions