I want to display 7 different images and plot them inside tkinter window. I only know to display it using OpenCV which actually displays the image outside the Tkinter GUI window. How to plot the images inside the GUI window?
Tkinter GUI:
I advise you read the documentation of tkinter as it has tons of example on how to achieve a soluction to your problem. I have made a sample GUI which updates image on the GUI with a randomized pixel picture. Note that there are a lot of different approaches how to do this. In my case I have made a class in which I display a frame and a button. The button calls a function to randomize the image (or changes to the next one in your case) and calls the function to update the frame with a new image. Hope it gives you a jump start. Cheers!
P.S.: for multiple images use more labels and functions;)
Code:
import tkinter as tk
from tkinter import *
import cv2
import numpy as np
from PIL import Image, ImageTk
class DisplayImage:
def __init__(self, master):
self.master = master
master.title("GUI")
self.image_frame = Frame(master, borderwidth=0, highlightthickness=0, height=20, width=30, bg='white')
self.image_frame.pack()
self.image_label = Label(self.image_frame, highlightthickness=0, borderwidth=0)
self.image_label.pack()
self.Next_image = Button(master, command=self.read_image, text="Next image", width=17, default=ACTIVE, borderwidth=0)
self.Next_image.pack()
def display_image(self, event=None):
self.cv2image = cv2.cvtColor(self.img, cv2.COLOR_BGR2RGBA)
self.from_array = Image.fromarray(self.cv2image)
self.imgt = ImageTk.PhotoImage(image=self.from_array)
self.image_label.configure(image=self.imgt)
def read_image(self, event=None):
self.img = np.random.randint(255, size=(250,250,3),dtype=np.uint8)
self.master.after(10, self.display_image)
def main():
root = tk.Tk()
GUI = DisplayImage(root)
GUI.read_image()
root.mainloop()
if __name__ == '__main__':
main()
Output:
If you are OK with using a wrapper with tkinter, then PySimpleGUI is a good choice.
There was a new Demo application posted this week that demonstrates how to show a webcam in a GUI window. There's another Demo posted that plays back a video file using OpenCV, again in a GUI window.
The code that generated that screen shot can be found here:
Open and Play Video Using PySimpleGU + OpenCV
You can start with the Demo and expand it by adding more buttons.
Related
I added a png image with transparent regions (alpha=0) to a tkinter canvas (see minimal example below). A mouse-click is recognized when clicking somewhere in the rectangle that contains the tkinter image.
How do I adjust the functionality such that any mouse binding (clicking, moving, etc.) is only called when the mouse is located on pixels with non-zero alpha values of the image?
Tux (linux mascot) example image :
try:
# Tkinter for Python 2.xx
import Tkinter as tk
except ImportError:
# Tkinter for Python 3.xx
import tkinter as tk
image_path = "./tux.png"
class Application(tk.Frame):
def __init__(self, master):
self.master = master
tk.Frame.__init__(self, master)
self.canvas = tk.Canvas(self, width=600, height=600)
self.canvas.pack(fill="both", expand=True)
# create an example image
self.tk_image = tk.PhotoImage(file=image_path)
self.image_obj= self.canvas.create_image(200, 200, anchor = 'center',
image=self.tk_image)
self.canvas.tag_bind(self.image_obj, '<Button-1>', self.clicked)
def clicked(self, event):
print("I am tux.")
def main():
app_win = tk.Tk()
app = Application(app_win).pack(fill='both', expand=True)
app_win.mainloop()
if __name__ == '__main__':
main()
How do I adjust the functionality such that any mouse binding (clicking, moving, etc.) is only called when the mouse is located on pixels with non-zero alpha values of the image?
You can't. That's simply not something that tkinter directly supports. Unfortunately, tkinter's support of transparency is a bit lacking.
What you might be able to do, however, is have the bound function get the image object, compute which pixel was clicked on, and then query the image instance to get the color of that pixel.
So I have 2 images, 1 image is supposed to be the background and the other 1 is just an image of a character.
I am able to put one image over the other but the image has white borders even though it's a PNG file.
This is how it looks like:
This is how I want it to look like:
Here are the two separte images:
https://imgur.com/a/SmE5lgC
Sorry that I didnt post the images directly but I can not since I do no have 10 reputation points.
I've tried converting it to RGBA but same thing happened.
from tkinter import *
from PIL import Image
root = Tk()
root.title("Game")
background = PhotoImage(file="back.png")
backgroundlabel = Label(root, image=background)
backgroundlabel.pack()
character = PhotoImage(file="hero.png")
characterlabel = Label(root, image=character)
characterlabel.place(x=0,y=0)
root.mainloop()
You just need to use the canvas widget in Tkinter. Only the canvas widget supports transparency. This has to do with how Tkinter draws the display. As of right now, your code is just overlaying two images. Tkinter does not know how to compose them with transparency unless you use the canvas widget.
See the following code:
from tkinter import *
from PIL import Image
root = Tk()
root.title("Game")
frame = Frame(root)
frame.pack()
canvas = Canvas(frame, bg="black", width=700, height=400)
canvas.pack()
background = PhotoImage(file="background.png")
canvas.create_image(350,200,image=background)
character = PhotoImage(file="hero.png")
canvas.create_image(30,30,image=character)
root.mainloop()
All I did was download the images you provided. I did not modify the images. So, the bottom line is that you just need to use the canvas widget.
VoilĂ !
Note: The question asked is a duplicate of How do I make Tkinter support PNG transparency?
Can tkinter create custom buttons from an image or icon like this?
It's possible!
If you check out the button documentation, you can use an image to display on the button.
For example:
from tkinter import *
root = Tk()
button = Button(root, text="Click me!")
img = PhotoImage(file="C:/path to image/example.gif") # make sure to add "/" not "\"
button.config(image=img)
button.pack() # Displaying the button
root.mainloop()
This is a simplified example for adding an image to a button widget, you can make many more cool things with the button widget.
I created a library called CustomTkinter, and with it you can create more or less exactly what is shown in the images above. CustomTkinter provides new widgets for Tkinter, which can be customised in color and shape. Here I tried to create something similar to the image above:
You can find the example code to the above image here.
There is not also a Button, but many other elements, and it also supports a dark and light theme:
You can check out the library here:
https://github.com/TomSchimansky/CustomTkinter
A simple example would be:
import tkinter
import customtkinter
customtkinter.set_appearance_mode("System")
customtkinter.set_default_color_theme("blue")
root_tk = customtkinter.CTk() # create CTk window like the Tk window
root_tk.geometry("400x240")
def button_function():
print("button pressed")
# Use CTkButton instead of tkinter Button
button = customtkinter.CTkButton(master=root_tk, command=button_function)
button.place(relx=0.5, rely=0.5, anchor=tkinter.CENTER)
root_tk.mainloop()
which gives the following on macOS:
I used the code below (with different variable names for each section) to create a background image for each tkinter window. Each of these is initiated in a function and both work fine independently.
When loading one function from another however, the second fails to display an image. (I have tried importing all relevant in each function aswell). It works in the case that use tk.destruct(), however if If I want to keep it open, or hide it with . withdraw(), the image fails to display, rendering the second window useless.
background_image=tk.PhotoImage(...)
background_label = tk.Label(parent, image=background_image)
background_label.place(x=0, y=0, relwidth=1, relheight=1)
Ok I've made up a solution for you. Basically all you need is to use tk.Toplevel() for the second tkinter window and make sure that the 'parent' is root2 so the image will appear in the second window.
I have used buttons for the images, you had labels so you may wish to change this, but buttons gave me a way to open a new tk window easily, I have also used .pack(), not .place(), as it was faster for me. May also be helpful for you to know that I used python 3.3 with windows so you might need a capital T for tkinter.
import tkinter as tk
root1 = tk.Tk()
def new_window():
root2 = tk.Toplevel()
# click the last button and all tk windows close
def shutdown():
root1.destroy()
root2.destroy()
background_image2 = tk.PhotoImage(file = '...')
background_button2 = tk.Button(root2, image = background_image2, command = shutdown)
background_button2.pack()
root2.mainloop()
background_image1 = tk.PhotoImage(file = '...')
# have used a button not a label for me to make another tk window
background_button1 = tk.Button(root1, image = background_image1, command = new_window)
background_button1.pack()
root1.mainloop()
#user2589273 Next time you should add more code so answers can be easily given, and tailored to you, just a suggestion. Hope this helps.
I have this code here that creates a Tkinter Canvas widget, then embeds an image within it.
import Tkinter
from PIL import ImageTk, Image
class image_manip(Tkinter.Tk):
def __init__(self):
Tkinter.Tk.__init__(self)
self.configure(bg='red')
self.ImbImage = Tkinter.Canvas(self, highlightthickness=0, bd=0, bg='blue')
self.ImbImage.pack()
self.i = ImageTk.PhotoImage(Image.open(r'test.png'))
self.ImbImage.create_image(150, 100, image=self.i)
def run():
image_manip().mainloop()
if __name__ == "__main__":
run()
I'd like to be able to create a blank image within the Canvas widget, so that I could do pixel by pixel manipulation within the widget. How would one go about this?
To create a new blank image (rather than opening one), you can use the Image.new(...) method in place of your Image.open(...). It is described in The Image Module.
Then call self.i.put(...) to do pixel-by-pixel manipulation. (i is the PhotoImage object as in your example.)
Here's some general information on The Tkinter PhotoImage Class.