I made a GUI in which I can load an image from disk and convert the mouse motion ( drawing the contours ) into coordinates. Now I need to convert the coordinates into a binary image and I don't know how.
Here is my code:
from Tkinter import *
from tkFileDialog import askopenfilename
from PIL import Image, ImageTk
import numpy as np
import cv2
class Browse_image :
def __init__ (self,master) :
frame = Frame(master)
frame.grid(sticky=W+E+N+S)
self.browse = Button(frame, text="Browse", command = lambda: browseim(self))
self.browse.grid(row=13, columnspan=1)
self.photo = PhotoImage(file="browse.png")
self.label = Label(frame, image=self.photo)
self.label.grid(row=1,rowspan=10)
self.label.bind('<B1-Motion>', self.mouseevent)
def mouseevent(self,event):
w=self.photo.width()
h=self.photo.height()
a = np.zeros(shape=(h,w))
#print event.x, event.y
a[event.x,event.y]=1
plt.imsave('binary.png', a, cmap=cm.gray)
def browseim(self):
path = askopenfilename(filetypes=(("png files","*.png"),("jpeg files",
"*.jpeg")) )
if path:
img = Image.open(path)
self.photo = ImageTk.PhotoImage(img)
self.label.configure(image = self.photo)
#self.label.image = self.photo
root= Tk()
b= Browse_image(root)
root.mainloop()
`
Your issue is that you are creating a new empty array at each mouse event with the line a = np.zeros(shape=(h,w)) in mouseevent. To fix that you should have a declared in the __init__ as an attribute (ie self.a = np.zeros(shape=(h,w))) so that you can acces and update it without overwriting it in your mouseevent function.
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 question already has answers here:
Why does Tkinter image not show up if created in a function?
(5 answers)
Closed 2 years ago.
I am trying to make this UI from a stimulus as part of an assessment for school. I tried to import the provided school logo and banner on the top frame of the page and put images on the canvas but have yet to achieve any results. When I run the code, the pictures won't load at all. The code that I was working with is as followed:
from tkinter import *
import random
import time
import sqlite3
from tkinter import simpledialog
from tkinter import messagebox
from tkcalendar import *
from tkinter import ttk
import math
from PIL import Image, ImageTk
import winsound
#-------------Frames setup--------------------------
class VendingApp(Tk):
def __init__(self):
Tk.__init__(self)
self._frame = None
self.switch_frame(Home)
def switch_frame(self, frame_class):
#Destroys current frame and replaces it with a new one.
new_frame = frame_class(self)
if self._frame is not None:
self._frame.destroy()
self._frame = new_frame
self._frame.pack()
####-----------------------Home page---------------------------
class Home(Frame):
def __init__(self, master):
Frame.__init__(self, master)
topFrame = Frame(self,width = 1024, height = 100, bd = 2, bg = "black")
topFrame.pack()
canvas_for_logo = Canvas(topFrame, height=100, width=100, bg = 'green') ##logo image
canvas_for_logo.grid(row=0, column=0, sticky='ne')
img_logo = Image.open("pic/sitelogo.png")
img_logo = img_logo.resize((40,40), Image.ANTIALIAS)
logo = ImageTk.PhotoImage(img_logo)
canvas_for_logo.create_image(0, 0, anchor=NW, image=logo)
canvas_for_banner = Canvas(topFrame, bg='red', height=100, width=924) #banner image
canvas_for_banner.grid(row=0, column=1, sticky='nw')
img_banner = Image.open("pic/banner.jpg")
img_banner = img_banner.resize((40,40), Image.ANTIALIAS)
banner = ImageTk.PhotoImage(img_banner)
canvas_for_banner.create_image(0, 0, anchor=NW, image=banner)
MidFrame = Frame(self,width = 1024, height = 628, bd = 2)
MidFrame.pack()
MidFrame.grid_propagate(False)
BottomFrame = Frame(self,width = 1024, height = 50, bd = 2, bg = "black")
BottomFrame.pack()
BottomFrame.grid_propagate(False)
if __name__ == "__main__":
root = VendingApp()
#Sets the size of the window
root.geometry("1024x768")
#Renames the TITLE of the window
root.title("Vending machine")
root.geometry("1024x768")
root.resizable(False, False)
root.mainloop()
I decided to make a separate file to test if the image would load without class, and it did. Codes are as followed:
from tkinter import ttk
from tkinter import*
import time
from PIL import Image, ImageTk
root = Tk()
canvas_for_logo = Canvas(root, height=100, width=100)
canvas_for_logo.pack()
img = Image.open("pic/sitelogo.png")
img = img.resize((105,105), Image.ANTIALIAS)
logo = ImageTk.PhotoImage(img)
canvas_for_logo.create_image(0, 0, anchor=NW, image=logo)
canvas_for_banner = Canvas(root, bg='red', height=100, width=924) #banner image
canvas_for_banner.pack()
img_banner = Image.open("pic/banner.jpg")
img_banner = img_banner.resize((924,100), Image.ANTIALIAS)
banner = ImageTk.PhotoImage(img_banner)
canvas_for_banner.create_image(0, 0, anchor=NW, image=banner)
root.mainloop()
Can someone please tell me what I did wrong? All replies are much appreciated. Thank you.
This is a typical Tkinter bug. I don't want to go into details cause I don't fully understand why it happens either, but it has something to do with the garbage collector and the fact that it doesn't consider the objects you have created for storing those images like being in use, so it deletes them; or something like that.
Luckily, it has an easy solution: you can either create an internal list variable, let say, self._images that stores each image you are using, something like:
self._images = list()
(...)
self._images.append(logo)
(...)
self._images.append(banner)
Or, you could assign to each canvas instance an attribute image (or img, it doesn't really matters) that stores the image instance it is going to carry. In your code, it will look similar to:
canvas_for_logo.image = logo
(...)
canvas_for_banner.image = banner
This way, you can avoid the garbage collector deleting what it shouldn't, cause now it acknowledges that this instances are being in use.
I'm trying to display a thumbnail image in tkinter by saving the image in memory using io.BytesIO(). I'm getting _tkinter.TclError: format error in bitmap data. The BitmapImage supports X11 bitmap image. So my question is how to convert my images to xbm before pass it to BitmapImage method?
from PIL import Image, ImageTk
import tkinter.scrolledtext as tkst
import tkinter as tk
import os, os.path
import io
class Example(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
img = Image.open("1.jpg")
image_size = 256, 256
img.thumbnail(image_size,Image.ANTIALIAS)
b = io.BytesIO()
img.save(b, 'gif')
p = b.getvalue()
photo = tk.BitmapImage(data=p)
self.photo = photo
self.imageview = tk.Label(self, image = self.photo, background="black")
self.imageview.grid(row=0, column=0, rowspan=2, sticky="nsew")
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True)
root.geometry("800x400")
root.mainloop()
Last time, I solved the problem using this code but sometimes the height of the image will get cut off.
image = Image.open("1.jpg")
basewidth = 900
wpercent = (basewidth/float(image.size[0]))
hsize = int((float(image.size[1])*float(wpercent)))
image = image.resize((basewidth,hsize),Image.ANTIALIAS)
self.photo = ImageTk.PhotoImage(image)
self.imageview.configure(image=self.photo)
I'm trying to make a python script that shows a image that is acessed on a listbox. This code that I got on the internet works:
import Tkinter as tk
from PIL import ImageTk, Image
window = tk.Tk()
path = 'img\\2015722_univ_sqs_sm.jpg'
img = ImageTk.PhotoImage(Image.open(path))
panel = tk.Label(window, image = img)
panel.pack(side = "bottom", fill = "both", expand = "yes")
window.mainloop()
But when I tried to adapt it do the listbox it stopped working.
from Tkinter import *
from PIL import ImageTk, Image
import glob
files = glob.glob('img\\*.jpg')
class App:
def __init__(self, root):
self.l = Listbox(root, width = 50, height = 15)
self.l.pack()
self.l.bind('<<ListboxSelect>>', self.lol)
self.c = Label(root)
self.c.pack()
for f in files:
self.l.insert(END, f)
def lol(self, evt):
path = files[self.l.curselection()[0]]
img = ImageTk.PhotoImage(Image.open(path))
self.c.image = img
self.c.pack()
root = Tk()
App(root)
root.mainloop()
What am I missing?
You must use the configure method of the label, and store a reference to the image somewhere.
self.c.image = img # save reference
self.c.configure(image=img) # configure the label
I would like to be able to swap out an image on a Tkinter label, but I'm not sure how to do it, except for replacing the widget itself.
Currently, I can display an image like so:
import Tkinter as tk
import ImageTk
root = tk.Tk()
img = ImageTk.PhotoImage(Image.open(path))
panel = tk.Label(root, image = img)
panel.pack(side = "bottom", fill = "both", expand = "yes")
root.mainloop()
However, when the user hits, say the ENTER key, I'd like to change the image.
import Tkinter as tk
import ImageTk
root = tk.Tk()
img = ImageTk.PhotoImage(Image.open(path))
panel = tk.Label(root, image = img)
panel.pack(side = "bottom", fill = "both", expand = "yes")
def callback(e):
# change image
root.bind("<Return>", callback)
root.mainloop()
Is this possible?
The method label.configure does work in panel.configure(image=img).
What I forgot to do was include the panel.image=img, to prevent garbage collection from deleting the image.
The following is the new version:
import Tkinter as tk
import ImageTk
root = tk.Tk()
img = ImageTk.PhotoImage(Image.open(path))
panel = tk.Label(root, image=img)
panel.pack(side="bottom", fill="both", expand="yes")
def callback(e):
img2 = ImageTk.PhotoImage(Image.open(path2))
panel.configure(image=img2)
panel.image = img2
root.bind("<Return>", callback)
root.mainloop()
The original code works because the image is stored in the global variable img.
Another option to do it.
Using object-oriented programming and with an interactive interface to update the image.
from Tkinter import *
import tkFileDialog
from tkFileDialog import askdirectory
from PIL import Image
class GUI(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
w,h = 650, 650
master.minsize(width=w, height=h)
master.maxsize(width=w, height=h)
self.pack()
self.file = Button(self, text='Browse', command=self.choose)
self.choose = Label(self, text="Choose file").pack()
self.image = PhotoImage(file='cualitativa.gif')
self.label = Label(image=self.image)
self.file.pack()
self.label.pack()
def choose(self):
ifile = tkFileDialog.askopenfile(parent=self,mode='rb',title='Choose a file')
path = ifile.name
self.image2 = PhotoImage(file=path)
self.label.configure(image=self.image2)
self.label.image=self.image2
root = Tk()
app = GUI(master=root)
app.mainloop()
root.destroy()
Replace 'cualitativa.jpg' for the default image you want to use.
Another solution that might be of help.
In my case, I had two tk.Tk() windows. When using ImageTk.PhotoImage(), the object defaults to setting its tk window to being the first one created. A simple fix to this is to pass the tk window that you want as such ImageTk.PhotoImage(img, master=your_window)
import tkinter as tk
from PIL import ImageTk, Image
if __name__ == '__main__':
main_window = tk.Tk()
second_window = tk.Tk()
main_canvas = Canvas(second_window)
main_canvas.pack()
filename = 'test.png'
img = Image.open(filename)
img = img.resize((300, 100), Image.ANTIALIAS)
logo = ImageTk.PhotoImage(img, master=second_window)
logo_label = Label(master=main_canvas, image=logo)
logo_label.image = logo
logo_label.pack()
main_window.mainloop()