I know that in CSS you can set the maximum size of an image by using max-width and max-height. I want to do the same thing with tkinter. I've already tried using Image.open("/path/to/file").resize(500), but I got the error TypeError: 'int' object is not iterable. Here is my code:
from tkinter import *
from PIL import Image, ImageTk
root=Tk()
current_image=0
images=[ImageTk.PhotoImage(Image.open("/users/27cadem/documents/display.png").resize(500))]
panel=Label(root,image=images[current_image])
panel.pack()
root.mainloop()
The code can be something like this:
from tkinter import Tk, Label
from PIL import Image, ImageTk
root = Tk()
file = 'img-path.png'
image = Image.open(file)
max_width = 500
pixels_x, pixels_y = tuple([int(max_width/image.size[0] * x) for x in image.size])
img = ImageTk.PhotoImage(image.resize((pixels_x, pixels_y)))
label = Label(root, image=img)
label.image = img
label.pack()
root.mainloop()
Related
I am doing a people counter in raspberry pi. I want to display an one image if someone comes in, and another one if someone comes out. Right now i am using the code below (that i took from another question here xd) to change the image that tkinter is displaying. The problem with this is thay it only shows the picture cat.jpg for a second, and then it shows a black screen and nothing happends.
import sys
if sys.version_info[0] == 2: # the tkinter library changed it's name from Python 2 to 3.
import Tkinter
tkinter = Tkinter #I decided to use a library reference to avoid potential naming conflicts with people's programs.
else:
import tkinter
from PIL import Image, ImageTk
import time
def updateRoot(root,imagen):
pilImage = Image.open(imagen)
w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.overrideredirect(1)
root.geometry("%dx%d+0+0" % (w, h))
root.focus_set()
root.bind("<Escape>", lambda e: (e.widget.withdraw(), e.widget.quit()))
canvas = tkinter.Canvas(root,width=w,height=h)
canvas.pack()
canvas.configure(background='black')
imgWidth, imgHeight = pilImage.size
if imgWidth > w or imgHeight > h:
ratio = min(w/imgWidth, h/imgHeight)
imgWidth = int(imgWidth*ratio)
imgHeight = int(imgHeight*ratio)
pilImage = pilImage.resize((imgWidth,imgHeight), Image.ANTIALIAS)
image = ImageTk.PhotoImage(pilImage)
imagesprite = canvas.create_image(w/2,h/2,image=image)
root.update()
root = tkinter.Tk()
updateRoot(root,"Cat.jpg")
time.timesleep(5)
updateRoot(root,"Dog.jpg")
Before this I used this code
import tkinter
from PIL import Image, ImageTk
from tkinter import ttk
def updateRoot(root,imagen):
image1 = Image.open(imagen)
image2 = ImageTk. PhotoImage(image1)
image_label = ttk. Label(root , image =image2)
image_label.place(x = 0 , y = 0)
root.update()
That works fine, but it's not full screen.
First you should do the followings outside updateRoot():
make root window fullscreen (you can simply use root.attributes('-fullscreen', 1))
bind the <Escape> key
create the canvas and create_image() (you can use Label to do the same thing)
Then just update the image inside updateRoot().
Also you should use after() instead of time.sleep().
Below is an example:
try:
import Tkinter as tkinter
except:
import tkinter
from PIL import Image, ImageTk
def updateRoot(imagen):
# resize the image to fill the whole screen
pilImage = Image.open(imagen)
w, h = root.winfo_screenwidth(), root.winfo_screenheight()
image = ImageTk.PhotoImage(pilImage.resize((w,h)))
# update the image
canvas.itemconfig(imgbox, image=image)
# need to keep a reference of the image, otherwise it will be garbage collected
canvas.image = image
root = tkinter.Tk()
root.attributes('-fullscreen', 1)
root.bind('<Escape>', lambda _: root.destroy())
canvas = tkinter.Canvas(root, highlightthickness=0)
canvas.pack(fill=tkinter.BOTH, expand=1)
imgbox = canvas.create_image(0, 0, image=None, anchor='nw')
# show the first image
updateRoot('Cat.jpg')
# change the image 5 seconds later
root.after(5000, updateRoot, 'Dog.jpg')
root.mainloop()
Fixed your Black issue using labels, try this. i think you still need to resize image to fit screen
import sys
if sys.version_info[0] == 2: # the tkinter library changed it's name from Python 2 to 3.
import Tkinter
tkinter = Tkinter #I decided to use a library reference to avoid potential naming conflicts with people's programs.
else:
import tkinter
from PIL import Image, ImageTk
import time
from tkinter import *
import PIL.Image
def updateRoot(root,imagen):
w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.overrideredirect(1)
root.geometry("%dx%d+0+0" % (w, h))
root.focus_set()
root.bind("<Escape>", lambda e: (e.widget.withdraw(), e.widget.quit()))
img = PIL.Image.open(imagen)
root.tkimage = ImageTk.PhotoImage(img)
Label(root,image = root.tkimage).place(x=0, y=0, relwidth=1, relheight=1)
root.update()
root = tkinter.Tk()
updateRoot(root,"Cat.jpg")
time.sleep(3)
updateRoot(root,"Dog.jpg")
root.mainloop()
Hello I am having issues with resizing my picture. I am trying to resize the image to fit the blue drawing. However the way I am doing it, returns an error.
File "gui.py", line 42, in fileDialog
self.display = Label(image=self.photo.resize((800, 600),Image.ANTIALIAS))
AttributeError: 'PhotoImage' object has no attribute 'resize
I am just testing it to see if it fits by doing 800,600 I really don't know.
def fileDialog(self):
self.filename = filedialog.askopenfilename(title="Select")
self.label = ttk.Label(self.labelFrame, text="")
self.label.grid(column=1, row=2)
self.label.configure(text=self.filename)
self.photo= ImageTk.PhotoImage(file = self.filename)
self.display = Label(image=self.photo.resize((800, 600),Image.ANTIALIAS))
self.display.grid(row=0)
Is there something that I am doing incorrectly? Please advise.
You need to resize the image, not the photoimage.
import tkinter as tk
from PIL import Image, ImageTk
filename = 'bell.jpg'
img = Image.open(filename)
resized_img = img.resize((200, 100))
root = tk.Tk()
root.photoimg = ImageTk.PhotoImage(resized_img)
labelimage = tk.Label(root, image=root.photoimg)
labelimage.pack()
To address the new question, you do not have to know the filename at the time of label creation. The following code produces the same result:
import tkinter as tk
from PIL import Image, ImageTk
root = tk.Tk()
labelimage = tk.Label(root)
labelimage.pack()
filename = 'bell.jpg'
img = Image.open(filename)
resized_img = img.resize((200, 100))
root.photoimg = ImageTk.PhotoImage(resized_img)
labelimage.configure(image=root.photoimg)
So im trying to make an app that will display images, and the image I have is 1000*1000 but this is way too big, I need a way to resize the image. I've tried using PIL and ImageTK but that didn't work, here's my code so far:
from tkinter import *
app = Tk()
app.title('embeded image')
fname = Canvas(bg = 'black', height=100, width=100)
fname.pack(side=TOP)
image = PhotoImage('Sun.png')
image = image.resize((25, 25), Image.ANTIALIAS)
icon = fname.create_image(image=image)
fname.pack()
app.mainloop()
I've no idea why this doesn't work, im relatively new to Tkinter so sorry if it's obvious.
You mix two differnt class PhotoImage in tkinter which doesn't have resize and PIL.Image which have resize
import tkinter as tk
from PIL import Image, ImageTk
app = tk.Tk()
fname = tk.Canvas(height=200, width=200)
fname.pack()
pil_image = Image.open('Sun.png')
pil_image = pil_image.resize((25, 25), Image.ANTIALIAS)
image = ImageTk.PhotoImage(pil_image)
icon = fname.create_image((0,0), image=image, anchor='nw')
app.mainloop()
I'm trying to place a .png image within a LabelFrame in a Tkinter window. I imported PIL so .png image types should be supported (right?). I can't seem to get the image to show up.
Here is my revised code:
import Tkinter
from Tkinter import *
from PIL import Image, ImageTk
root = Tk()
make_frame = LabelFrame(root, text="Sample Image", width=150, height=150)
make_frame.pack()
stim = "image.png"
width = 100
height = 100
stim1 = stim.resize((width, height), Image.ANTIALIAS)
img = ImageTk.PhotoImage(image.open(stim1))
in_frame = Label(make_frame, image = img)
in_frame.pack()
root.mainloop()
With this code, I got an AttributeError that reads: "'str' has no attribute 'resize'"
#Mickey,
You have to call the .resize method on the PIL.Image object and not the filename, which is a string. Also, you may prefer to use PIL.Image.thumbnail instead of PIL.Image.resize, for reasons described clearly here. Your code was close, but this might be what you need:
import Tkinter
from Tkinter import *
from PIL import Image, ImageTk
root = Tk()
make_frame = LabelFrame(root, text="Sample Image", width=100, height=100)
make_frame.pack()
stim_filename = "image.png"
# create the PIL image object:
PIL_image = Image.open(stim_filename)
width = 100
height = 100
# You may prefer to use Image.thumbnail instead
# Set use_resize to False to use Image.thumbnail
use_resize = True
if use_resize:
# Image.resize returns a new PIL.Image of the specified size
PIL_image_small = PIL_image.resize((width,height), Image.ANTIALIAS)
else:
# Image.thumbnail converts the image to a thumbnail, in place
PIL_image_small = PIL_image
PIL_image_small.thumbnail((width,height), Image.ANTIALIAS)
# now create the ImageTk PhotoImage:
img = ImageTk.PhotoImage(PIL_image_small)
in_frame = Label(make_frame, image = img)
in_frame.pack()
root.mainloop()
I can't seem to get my PIL Image to work on canvas. Code:
from Tkinter import*
import Image, ImageTk
root = Tk()
root.geometry('1000x1000')
canvas = Canvas(root,width=999,height=999)
canvas.pack()
image = ImageTk.PhotoImage("ball.gif")
imagesprite = canvas.create_image(400,400,image=image)
root.mainloop()
Error:
Traceback (most recent call last):
File "C:/Users/Mark Malkin/Desktop/3d Graphics Testing/afdds.py", line 7, in <module>
image = ImageTk.PhotoImage("ball.gif")
File "C:\Python27\lib\site-packages\PIL\ImageTk.py", line 109, in __init__
mode = Image.getmodebase(mode)
File "C:\Python27\lib\site-packages\PIL\Image.py", line 245, in getmodebase
return ImageMode.getmode(mode).basemode
File "C:\Python27\lib\site-packages\PIL\ImageMode.py", line 50, in getmode
return _modes[mode]
KeyError: 'ball.gif'
I need to use PIL images not PhotoImages because I want to resize my images. Please don't suggest switching to Pygame because I want to use Tkinter.
Try creating a PIL Image first, then using that to create the PhotoImage.
from Tkinter import *
import Image, ImageTk
root = Tk()
root.geometry('1000x1000')
canvas = Canvas(root,width=999,height=999)
canvas.pack()
pilImage = Image.open("ball.gif")
image = ImageTk.PhotoImage(pilImage)
imagesprite = canvas.create_image(400,400,image=image)
root.mainloop()
(An old question, but the answers so far are only half-complete.)
Read the docs:
class PIL.ImageTk.PhotoImage(image=None, size=None, **kw)
image – Either a PIL image, or a mode string. [...]
file – A filename to load the image from (using Image.open(file)).
So in your example, use
image = ImageTk.PhotoImage(file="ball.gif")
or explicitly
image = ImageTk.PhotoImage(Image("ball.gif"))
(And remember – as you did correctly: Keep a reference to the image object in your Python program, otherwise it is garbage-collected before you seee it.)
You can import multiple image formats, and resize with this code. "basewidth" sets the width of your image.
from Tkinter import *
import PIL
from PIL import ImageTk, Image
root=Tk()
image = Image.open("/path/to/your/image.jpg")
canvas=Canvas(root, height=200, width=200)
basewidth = 150
wpercent = (basewidth / float(image.size[0]))
hsize = int((float(image.size[1]) * float(wpercent)))
image = image.resize((basewidth, hsize), PIL.Image.ANTIALIAS)
photo = ImageTk.PhotoImage(image)
item4 = canvas.create_image(100, 80, image=photo)
canvas.pack(side = TOP, expand=True, fill=BOTH)
root.mainloop()
I was banging my head against the wall for a while on this issue until I found the following:
http://effbot.org/pyfaq/why-do-my-tkinter-images-not-appear.htm
Apparently, Python's garbage collector can trash the ImageTk object. I imagine apps using alot of widgets (like mine) are more susceptible to this behavior.