How to open PIL Image in Tkinter on Canvas - python

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.

Related

Set the max width of an image in tkinter

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()

Resizing image Python Tkinter

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)

when trying to create a bitmap: _tkinter.TclError: bitmap "pyimage2" not defined

There is an image which I'd like to draw in different colors, so I converted it to a bitmap, but when trying to create it on the canvas I get an error.
This is the code:
import PIL.Image
from PIL import ImageTk
from tkinter import *
im = PIL.Image.open("lightbulb.gif")
small_im = im.resize((20,20), resample=PIL.Image.NEAREST).convert('1');
root = Tk()
canvas = Canvas(root,width=100,height=100,bg='black')
canvas.pack()
bitmap = ImageTk.BitmapImage(small_im)
bitmap_id = canvas.create_bitmap(3,3,background='', foreground='gray', bitmap=bitmap,
anchor=NW)
root.mainloop()
I get the following error:
Traceback (most recent call last):
File "/Users/ronen/Dropbox/trycanvas/bitmaps.py", line 13, in <module>
bitmap_id = canvas.create_bitmap(3,3,background="", foreground="gray", bitmap=bitmap, anchor=NW)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/tkinter/__init__.py", line 2486, in create_bitmap
return self._create('bitmap', args, kw)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/tkinter/__init__.py", line 2480, in _create
*(args + self._options(cnf, kw))))
_tkinter.TclError: bitmap "pyimage2" not defined
What am I doing wrong?
The tkinter canvas.create_bitmap() method expects its bitmap= option to be a string containing either the name of one of the standard bitmaps (which are 'error', 'gray75', 'gray50', 'gray25', 'gray12', 'hourglass', 'info', 'questhead', 'question', and 'warning') and which look like this:
Or the pathname of a file with one of your own in it in .xbm file format prefixed with an # character.
Below is how to modify your code so it saves the image you want to display in a temporary .xbm format file and then tells tkinter to use that:
import os
import PIL.Image
from PIL import ImageTk
from tempfile import NamedTemporaryFile
import tkinter as tk
im = PIL.Image.open("lightbulb.gif")
small_img = im.resize((20,20), resample=PIL.Image.NEAREST).convert('1');
with NamedTemporaryFile(suffix='.xbm', delete=False) as temp_img:
small_img.save(temp_img.name)
root = tk.Tk()
canvas = tk.Canvas(root, width=100, height=100, bg='black')
canvas.pack()
bitmap_id = canvas.create_bitmap(3, 3, background='', foreground='gray',
bitmap='#'+temp_img.name, anchor=tk.NW)
root.mainloop()
try: # Cleanup
os.remove(temp_img.name) # Get rid of named temporary file.
except FileNotFoundError:
pass
Okay, I now understand what's going on. ImageTk.BitmapImage actually return an image, not a bitmap, but it can be used to change the colors. So intead of:
bitmap = ImageTk.BitmapImage(small_im)
bitmap_id = canvas.create_bitmap(3,3,background='', foreground='gray', bitmap=bitmap,
anchor=NW)
I should have coded:
from_bitmap = ImageTk.BitmapImage(small_im, background='', foreground='gray')
bitmap_id = canvas.create_image(3,3, image=from_bitmap, anchor=NW)

I Cant get an image to be resized and displayed using tkinter

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()

How do I place an image (.png) within a `LabelFrame`, and resize it, in Tkinter?

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()

Categories

Resources