I'm trying to add a background image to a canvas in Python. So far the code looks like this:
from Tkinter import *
from PIL import ImageTk,Image
... other stuffs
root=Tk()
canvasWidth=600
canvasHeight=400
self.canvas=Canvas(root,width=canvasWidth,height=canvasHeight)
backgroundImage=root.PhotoImage("D:\Documents\Background.png")
backgroundLabel=root.Label(parent,image=backgroundImage)
backgroundLabel.place(x=0,y=0,relWidth=1,relHeight=1)
self.canvas.pack()
root.mainloop()
It's returning an AttributeError: PhotoImage
PhotoImage is not an attribute of the Tk() instances (root). It is a class from Tkinter.
So, you must use:
backgroundImage = PhotoImage("D:\Documents\Background.gif")
Beware also Label is a class from Tkinter...
Edit:
Unfortunately, Tkinter.PhotoImage only works with gif files (and PPM).
If you need to read png files you can use the PhotoImage (yes, same name) class in the ImageTk module from PIL.
So that, this will put your png image in the canvas:
from Tkinter import *
from PIL import ImageTk
canvas = Canvas(width = 200, height = 200, bg = 'blue')
canvas.pack(expand = YES, fill = BOTH)
image = ImageTk.PhotoImage(file = "C:/Python27/programas/zimages/gato.png")
canvas.create_image(10, 10, image = image, anchor = NW)
mainloop()
just change to :
image = Image.open("~~~path.png")
backgroundImage=ImageTk.PhotoImage(image)
believe me this will 100% work
from Tkinter import *
from PIL import ImageTk
canvas = Canvas(width = 200, height = 200, bg = 'blue')
canvas.pack(expand = YES, fill = BOTH)
image = ImageTk.PhotoImage(file = "C:/Python27/programas/zimages/gato.png")
canvas.create_image(10, 10, image = image, anchor = NW)
mainloop()
You are using root to Attribute PhotoImage this is impossible!
root is your window Tk() class so you cant Attribute it for PhotoImage because it's dosen't have it so you see AttributeError tkinter.Tk() and tkinter.PhotoImage is a different classes. and the same with tkinter.Label.
your code will not working with root.PhotoImage and root.Label.
try to PhotoImage and Label directly.
to create a Label:
backgroundlabel = Label(parent, image=img)
if use any types of png or jpg and jpeg you can't draw it with just PhotoImage you will need PIL library
pip3 install PIL
when you have it use it like:
from PIL import Image, ImageTk # import image so you can append the path and imagetk so you can convert it as PhotoImage
now get your full path image like:
C:/.../img.png
Now use it :
path = "C:/.../img.png" # Get the image full path
load = Image.open(path) # load that path
img = ImageTk.PhotoImage(load) # convert the load to PhotoImage
now you have your code work.
full code:
from Tkinter import *
from PIL import ImageTk,Image
... other stuffs
root = Tk()
canvasWidth = 600
canvasHeight = 400
self.canvas = Canvas(root,width=canvasWidth,height=canvasHeight)
path = "D:\Documents\Background.png" # Get the image full path
load = Image.open(path) # load that path
img = ImageTk.PhotoImage(load)
backgroundLabel = Label(parent,image=img)
backgroundLabel .place(x=0,y=0,relWidth=1,relHeight=1)
self.canvas .pack()
root .mainloop()
Hope this will helpfull.
Related
I am trying to resize an image I inserted in my Tkinter window, but keep receiving this error message: "AttributeError: 'PhotoImage' object has no attribute 'resize'"
This is my code to resize the image:
self.path = 'S:/Öffentliche Ordner/Logos/Core Solution/Logo/CoreSolution_Logo_RGB.jpg'
self.img = ImageTk.PhotoImage(Image.open(self.path))
self.resized = self.img.resize(50,50)
self.new_img = ImageTk.PhotoImage(self.resized)
self.label = Label(master, image = self.new_img)
self.label.pack()
self.Main = Frame(self.master)
How can I resolve this error? All help is welcomed and appreciated.
As in this tutorial, it looks like it is easier to import the file as an image. Then resize it, then convert it to PhotoImage. Can you give it a try ?
# Import the required libraries
from tkinter import *
from PIL import Image, ImageTk
# Create an instance of tkinter frame or window
win=Tk()
# Set the size of the tkinter window
win.geometry("700x350")
# Load the image
image=Image.open('download.png')
# Resize the image in the given (width, height)
img=image.resize((450, 350))
# Conver the image in TkImage
my_img=ImageTk.PhotoImage(img)
# Display the image with label
label=Label(win, image=my_img)
label.pack()
win.mainloop()
https://www.tutorialspoint.com/resizing-images-with-imagetk-photoimage-with-tkinter
As far as I can see, the Pillow Image.PhotoImage class is meant for displaying in tkinter but does not have all the methods of the tkinter.PhotoImage class.
Easiest is to resize the Pillow.Image before converting to Pillow Image.PhotoImage.
from tkinter import *
from PIL import Image, ImageTk
master = Tk()
path = 'images/cleese.png'
img = Image.open(path)
img.thumbnail((50,50)) # Resize Pillow Image
new_img = ImageTk.PhotoImage(img) # Convert
label = Label(master, image=new_img)
label.pack()
master.mainloop()
Try this. I did not test.
path = Image.open('S:/Öffentliche Ordner/Logos/Core Solution/Logo/CoreSolution_Logo_RGB.jpg'
self.resized = path.resize{(50,50),Image.ANTIALIAS)
self.img = ImageTk.PhotoImage(self.resized)
self.label = Label(master, image = self.new_img)
self.label.pack()
self.Main = Frame(self.master)
This is my code for the button that opens an app:
Modules:
import tkinter as tk
from tkinter import *
from PIL import ImageTk, Image
from subprocess import Popen
Importing Image:
path = ("C:\Pictures\GoogleLogo.png")
img = Image.open(path)
img = img.resize((96, 96), Image.ANTIALIAS)
img = ImageTk.PhotoImage(img)
Generic Canvas Button:
def openCalc():
Popen("calc.exe")
openCalcWin = tk.Button(text='Calculator', command=openCalc, bg="Grey", height = 6, width = 10)
canvas.create_window(1167,714, window=openCalcWin)
What I have Tried:
I attempted to make the background of the button into an image by using bg or img. But this just creates an tiny image logo that can't be clicked. Indicating that there was an error loading the image, but there was no error code or anything in the IDLE Shell.
There was other attempts of code that I forgot, but most of them ends up the same: no button appeared and no error code.
Edit:
import tkinter as tk
from PIL import ImageTk, Image
from subprocess import Popen
##Application Window:
root=tk.Tk()
root.title("Virtual Desktop")
root.resizable(False, False)
#Determine Window Resolution
canvas = tk.Canvas(root, width=1280, height=780, bg="#263D42")
canvas.pack()
#Importing Calulator Image
path = ("C:\Pictures\CalcLogo.png")
img = Image.open(path)
img = img.resize((96, 96), Image.ANTIALIAS)
img = ImageTk.PhotoImage(img)
#Calculator Button
def openCalc():
Popen("calc.exe")
openCalcWin = tk.Button(text='Calculator', command=openCalc, bg="Grey", height = 6, width = 10)
canvas.create_window(1167,714, window=openCalcWin)
The following works for me. The most important change was to specify an image= keyword argument, when creating the Button.
The other thing I noted was the:
path = ("C:\Pictures\CalcLogo.png")
you had. The parentheses are unnecessary (but don't hurt), however you need to add an r prefix to all strings containing back-slash characters like paths on Windows.
path = r"C:\Pictures\CalcLogo.png"
or just use forward-slashes (which work fine on Windows):
path = "C:/Pictures/CalcLogo.png"
Full code:
import tkinter as tk
from PIL import ImageTk, Image
from subprocess import Popen
##Application Window:
root=tk.Tk()
root.title("Virtual Desktop")
root.resizable(False, False)
#Determine Window Resolution
canvas = tk.Canvas(root, width=1280, height=780, bg="#263D42")
canvas.pack()
#Importing Calulator Image
path = "8-ball.png" # My own image.
img = Image.open(path)
img = img.resize((96, 96), Image.ANTIALIAS)
img = ImageTk.PhotoImage(img)
#Calculator Button
def openCalc():
Popen("calc.exe")
openCalcWin = tk.Button(text='Calculator', command=openCalc, bg="Grey",
image=img)
canvas.create_window(1167,714, window=openCalcWin)
root.mainloop()
I found this solution. You can check it learn about it yourself, but basically you do not provide any args when creating the obj/Button, you only provide the root, image and command, and it should work.
Something like this:
import tkinter as tk
from tkinter import *
from PIL import ImageTk, Image
from subprocess import Popen
root = Tk()
path = ("C:\Pictures\GoogleLogo.png")
img = Image.open(path)
img = img.resize((96, 96), Image.ANTIALIAS)
img = ImageTk.PhotoImage(img)
def openCalc():
Popen("calc.exe")
openCalcWin = tk.Button(text='Calculator', image=img, command=openCalc)
openCalcWin.pack()
root.mainloop()
if you want, you can look at some examples and learn more here - https://www.activestate.com/resources/quick-reads/how-to-add-images-in-tkinter/
How do I insert a JPEG image into a Python 2.7 Tkinter window? What is wrong with the following code? The image is called Aaron.jpg.
#!/usr/bin/python
import Image
import Tkinter
window = Tkinter.Tk()
window.title("Join")
window.geometry("300x300")
window.configure(background='grey')
imageFile = "Aaron.jpg"
window.im1 = Image.open(imageFile)
raw_input()
window.mainloop()
Try this:
import tkinter as tk
from PIL import ImageTk, Image
#This creates the main window of an application
window = tk.Tk()
window.title("Join")
window.geometry("300x300")
window.configure(background='grey')
path = "Aaron.jpg"
#Creates a Tkinter-compatible photo image, which can be used everywhere Tkinter expects an image object.
img = ImageTk.PhotoImage(Image.open(path))
#The Label widget is a standard Tkinter widget used to display a text or image on the screen.
panel = tk.Label(window, image = img)
#The Pack geometry manager packs widgets in rows or columns.
panel.pack(side = "bottom", fill = "both", expand = "yes")
#Start the GUI
window.mainloop()
Related docs: ImageTk Module, Tkinter Label Widget, Tkinter Pack Geometry Manager
import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
win = tk. Tk()
image1 = Image. open("Aoran. jpg")
image2 = ImageTk. PhotoImage(image1)
image_label = ttk. Label(win , image =.image2)
image_label.place(x = 0 , y = 0)
win.mainloop()
from tkinter import *
from PIL import ImageTk, Image
window = Tk()
window.geometry("1000x300")
path = "1.jpg"
image = PhotoImage(Image.open(path))
panel = Label(window, image = image)
panel.pack()
window.mainloop()
I want to change png image to gif image using python3.6 how can I do that? i'm making a GUI program with tkinter and i haver to change png to gif image so i can display on my program please help
tk = Tk()
tk.configure(bg = 'white')
tk.title("SearchKeyWord V2.0")
canvas = Canvas(tk,width = 880, height = 550,bd = 0,highlightthickness = 0)
canvas.pack()
txt = Entry(tk)
txt.place(relx = .9,rely = .3,anchor = "c")
LOGO = PhotoImage(file = 'SKW-LOGO.gif')
button_1 = PhotoImage(file = 'button.gif')
button_2 = PhotoImage(file = 'button_news_1d.gif')
button_3 = PhotoImage(file = 'button_news_1w.gif')
button = tkinter.Button(tk,image = button_1,command = search)
button_news_1d = tkinter.Button(tk,image = button_2)
button_news_1w = tkinter.Button(tk,image = button_3)
canvas.create_image(0,0,anchor = NW, image = LOGO)
button.place(relx=.8, rely=.5, anchor="c")
button_news_1d.place(relx =.8,rely = .7, anchor = "c" )
button_news_1w.place(relx =.8,rely = .9, anchor = "c" )
tk.update()
tk.mainloop()
You can use pillow’s ImageTk to load the image directly as png.
import tkinter as tk
from PIL import Image, ImageTk
image_o = Image.open("photo.png")
image = ImageTk.PhotoImage(image_o)
# Use image as to how you would in tkinter
root = tk.Tk()
button = tk.Button(root, image = image)
button.pack()
root.mainloop()
Unlike tkinter‘s PhotoImage, which limits you to use only a certain type of images including the widespread gif file, ImageTk’s PhotoImage can take any PIL recognizable image type by having pillow to load it first.
http://pillow.readthedocs.io/en/4.1.x/reference/ImageTk.html
If you don’t have pillow yet, do pip install pillow
Added: (thanks to Mike - SMT’s valuable comment)
In newer releases of tk/tkl 8.6+, tk natively supports png image format.
Warning: this version of tk isn’t supported in some python interpreters.
https://www.tcl.tk/software/tcltk/8.6.html
I try to show a image in a label when I push a button, but the image are too large and I have tried to resize the image. I have created this function:
def image_resize(imageFile):
width = 500
height = 300
image = Image.open(imageFile)
im2 = image.resize((width, height), Image.ANTIALIAS)
return im2
To show the image I have created this function:
def show_image():
label_originalimage ['image'] = image_tk
And the button with the command=show_image:
filename = 'bild_1.jpg'
image_resize = image_resize(filename)
image_tk = PhotoImage(image_resize)
button_open = Button(frame_open, text='Open Image', command=show_image)
I get only this:
TypeError : __str__ returned non-string (type instance)
The PhotoImage class from tkinter takes a filename as an argument, and as it cannot convert the image into a string, it complains. Instead, use the PhotoImage class from the PIL.ImageTk module. This works for me:
from tkinter import *
from PIL import ImageTk, Image
def image_resize(imageFile):
width = 500
height = 300
image = Image.open(imageFile)
im2 = image.resize((width,height), Image.ANTIALIAS)
return im2
def show_image():
label_originalimage ['image'] = image_tk
root = Tk()
filename = './Pictures/Space/AP923487321702.jpg'
image_resize = image_resize(filename)
image_tk = ImageTk.PhotoImage(image_resize)
label_originalimage = Label(root)
label_originalimage.pack()
button_open = Button(root, text='Open Image', command=show_image)
button_open.pack()
root.mainloop()
Notice the change from image_tk = PhotoImage(image_resize) to image_tk = ImageTk.PhotoImage(image_resize).
I had the same problem when I try to construct a canvas image item for
tkinter from a tkinter PhotoImage. The latter was constructed from some
image data in memory (in my case an opencv image). The same exception
occurs if I simply try to convert the PhotoImage to a string.
I guess there is a bug in the conversion method __str__ of the PhotoImage,
making it simply returns the image source. If constructed from a file name
(see below) this works fine. If constructed from some image data, this is not
of type string and yields an exception.
Unfortunately, using the compatible PhotoImage from PIL's
ImageTk module like matsjoyce suggested didn't help me either because I experienced an even worse problem, probably a platform or library version dependent bug (I used OS X 10.11.6, python 3.5, tkinter 8.6, PIL 1.1.7): Now the python script crashed at the construction of the canvas image item with a "Bus Error".
The only workaround I am aware of was to store the image data into a temporary file and use a tkinter PhotoImage constructed from that file name. (Trying the same with the PIL PhotoImage still crashes.)
#!/usr/bin/env python3
import tkinter
import tempfile
import cv2
def opencv2photoimg(opencv_img):
"""Convert OpenCV (numpy) image to tkinter photo image."""
# ugly workaround: store as file & load file, because direct
# construction leads to a crash on my platform
tmpfile = tempfile.NamedTemporaryFile(suffix='.png', delete=True)
# ^^^ I am using PNGs only, you might want to use another suffix
cv2.imwrite(tmpfile.name, opencv_img)
return tkinter.PhotoImage(file=tmpfile.name)
# load image
img = cv2.imread('test.png')
# do something w/ the image ...
# setup tk window w/ canvas containing an image
root = tkinter.Tk()
canvas = tkinter.Canvas(root, width=img.shape[1], height=img.shape[0])
canvas.pack()
# keep reference to PhotoImage to avoid it being garbage collected
# (well known tkinter bug for canvas image items)
photo_img = opencv2photoimg(img)
# create a canvas item
img_item = canvas.create_image(0, 0, anchor=tkinter.NW, image=photo_img)
# display the window
tkinter.mainloop()
I do not think it's elegant, but it works.
Yes it works, but yeeeucchh - what I way to have to do it.
Surely there is a better way.
Here is my test code I got to starting from here....
import tkinter
from PIL import Image
import numpy
import time
import io
#python2 version (original) -> 120fps
#full physical file io and new image each cycle -> 130fps
#reuse PIL Image instead of create new each time -> 160fps
class mainWindow():
times=1
timestart=time.clock()
data=numpy.array(numpy.random.random((400,500))*100,dtype=int)
theimage = Image.frombytes('L', (data.shape[1],data.shape[0]),data.astype('b').tostring())
def __init__(self):
self.root = tkinter.Tk()
self.frame = tkinter.Frame(self.root, width=500, height=400)
self.frame.pack()
self.canvas = tkinter.Canvas(self.frame, width=500,height=400)
self.canvas.place(x=-2,y=-2)
self.root.after(0,self.start) # INCREASE THE 0 TO SLOW IT DOWN
self.root.mainloop()
def start(self):
global data
global theimage
self.theimage.frombytes(self.data.astype('b').tobytes())
self.theimage.save('work.pgm')
self.photo = tkinter.PhotoImage(file='work.pgm')
self.canvas.create_image(0,0,image=self.photo,anchor=tkinter.NW)
self.root.update()
self.times+=1
if self.times%33==0:
print("%.02f FPS"%(self.times/(time.clock()-self.timestart)))
self.root.after(10,self.start)
self.data=numpy.roll(self.data,-1,1)
if __name__ == '__main__':
x=mainWindow()
Here it is: I found that the input data to photoimage can be a byte array that looks like a ppm file, although it only appears to work on a subset of legal ppm (e.g. 16 bit values don't work)
So for future reference.......
import tkinter
import numpy
import time
#python2 version (original) -> 120fps
#full physical file io and new image each cycle -> 130fps
#reuse PIL Image instead of create new each time -> 160fps
#and... direct image into tkinter using ppm byte array -> 240 fps
class mainWindow():
times=1
timestart=time.clock()
data=numpy.array(numpy.random.random((400,500))*900,dtype=numpy.uint16)
def __init__(self):
self.root = tkinter.Tk()
self.frame = tkinter.Frame(self.root, width=500, height=400)
self.frame.pack()
self.canvas = tkinter.Canvas(self.frame, width=500,height=400)
self.canvas.place(x=-2,y=-2)
xdata = b'P5 500 400 255 ' + self.data.tobytes()
self.photo = tkinter.PhotoImage(width=500, height=400, data=xdata, format='PPM')
self.imid = self.canvas.create_image(0,0,image=self.photo,anchor=tkinter.NW)
self.root.after(1,self.start) # INCREASE THE 0 TO SLOW IT DOWN
self.root.mainloop()
def start(self):
global data
xdata = b'P5 500 400 255 ' + numpy.clip(self.data,0,255).tobytes()
self.photo = tkinter.PhotoImage(width=500, height=400, data=xdata, format='PPM')
if True:
self.canvas.itemconfig(self.imid, image = self.photo)
else:
self.canvas.delete(self.imid)
self.imid = self.canvas.create_image(0,0,image=self.photo,anchor=tkinter.NW)
self.times+=1
if self.times%33==0:
print("%.02f FPS"%(self.times/(time.clock()-self.timestart)))
self.root.update()
self.root.after(0,self.start)
self.data=numpy.roll(self.data,-1,1)
if __name__ == '__main__':
x=mainWindow()