How to display the image after clicking the button? - python

I am trying to make an application that applies filters to an image but it shows an exception after reading image_label_filtered=Label(image=filtered_image) saying _tkinter.TclError: image doesn't exist.
from tkinter import *
import cv2
import numpy as np
from matplotlib import pyplot as plt
from PIL import ImageTk,Image
root=Tk()
root.title("image processing")
original_image=ImageTk.PhotoImage(Image.open("E:/college materials/third year first term/image processing/section/noised_image.png"))
original_image_for_filter=cv2.imread("E:/college materials/third year first term/image processing/section/noised_image.png")
image_label=Label(image=original_image)
image_label.grid(row=0,column=0)
def button_Blur():
filtered_image=cv2.blur(original_image_for_filter,(5,5))
image_label_filtered=Label(image=filtered_image)
image_label_filtered.grid(row =0, column=1)
button_blur=Button(root,text="apply blur filter",command=button_Blur)
button_blur.grid(row=1,column=0)
root.mainloop()

You need to convert the image to tkinter.PhotoImage compatible format, like ImageTk.PhotoImage in order to be used as the image of a Label widget:
def button_Blur():
image = cv2.blur(original_image_for_filter, (5,5))
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # BGR to RGB
image = Image.fromarray(image) # convert to Image format
filtered_image = ImageTk.PhotoImage(image) # convert to PhotoImage format
image_label_filtered = Label(image=filtered_image)
image_label_filtered.grid(row =0, column=1)
# keep a reference of the image to avoid garbage collected
image_label_filtered.image = filtered_image

Related

I am getting an AttributeError when I try to resize an image I have inserted to a Tkinter window

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)

UnboundLocalError: local variable 'input_img' referenced before assignment Tkinter

I tried to detect blue color from entry input image using both Tkinter and OpenCV where when 'Display Image 2' button is pressed second window will display and I was expecting the image where blue color from image is detected to displays on the second window but turned out it doesn't. Why?
Output Error: UnboundLocalError: local variable 'input_img' referenced before assignmentTkinter
from tkinter import *
from PIL import ImageTk, Image
import tkinter as tk
import cv2
import numpy as np
window = Tk()
window.title("Color detector")
window.geometry("800x500")
input_img = tk.Entry(window)
input_img.pack()
def detect_color():
new_wind = Toplevel()
new_wind.title('Ur mom')
# Get Image
input_img = str(input_img.get())
global img
path = r'C:\\users\\HP\\Documents\\' + input_img
img = ImageTk.PhotoImage(Image.open(path))
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower_blue = np.array([[90,50,50]])
upper_blue = np.array([[130,255,255]])
mask = cv2.inRange(hsv,lower_blue,upper_blue)
result = cv2.bitwise_and(img,img,mask=mask)
display_result = Label(new_wind,image=result)
display_result.pack()
display_img = tk.Button(window, text='Display Image 2',command=detect_color)
display_img.pack()
window.mainloop()
So this is the image I use in this case:
The output:
Output I expected:

How to create a save button in my tkinter project to save the output?

I had created the program with the combination of tkinter and cv2 for turning color image to black and white but I am not able to understand how to add the button that will save the black and white image. How to do it?
# importing the Packages
import cv2 # importing cv2 package for converting the colored imaged to gray or vice versa
import tkinter as tk # importing tkinter package for creating Gui and its instance io created is tk
from tkinter import filedialog as fd # importing the filedialog package from tkinter to open the file default file explorer
from PIL import Image, ImageTk # Python imaginary library for performing operation on images
root = tk.Tk()
root.title("Color to blackNwhite Convertor")
root.config(bg='#FFFAFA')
def selectimage():
global panelA,panelB #used two global variables to create two panels
location = fd.askopenfilename()
if len(location) > 0:
image = cv2.imread(location)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# convert the images to PIL format...
image = Image.fromarray(image)
gray = Image.fromarray(gray)
# ...and then to ImageTk format
image = ImageTk.PhotoImage(image)
gray = ImageTk.PhotoImage(gray)
if panelA is None or panelB is None:
panelA = tk.Label(image=image)
panelA.image = image
panelA.pack(side="left", padx=10, pady=10)
panelB = tk.Label(image=gray)
panelB.image = gray
panelB.pack(side="right", padx=10, pady=10)
else:
panelA.configure(image=image)
panelB.configure(image=gray)
panelA.image = image
panelB.image = gray
panelA = None
panelB = None
btn = tk.Button(root, text="Select an image",font=('arial',10,'bold'),bg="cyan", command=selectimage)
btn.config(height=5,width=15)
btn.pack(side="bottom", fill="both", expand="yes", padx="10", pady="10")
# kick off the GUI
root.mainloop()
You should keep the reference of the image returned by Image.fromarray(gray), then create a button to trigger a callback to save the gray image using save() on the gray image:
# importing the Packages
import cv2 # importing cv2 package for converting the colored imaged to gray or vice versa
import tkinter as tk # importing tkinter package for creating Gui and its instance io created is tk
from tkinter import filedialog as fd # importing the filedialog package from tkinter to open the file default file explorer
from PIL import Image, ImageTk # Python imaginary library for performing operation on images
root = tk.Tk()
root.title("Color to blackNwhite Convertor")
root.config(bg='#FFFAFA')
def selectimage():
global panelA,panelB #used two global variables to create two panels
global gray_image ### for saving reference to the gray image
location = fd.askopenfilename()
if len(location) > 0:
image = cv2.imread(location)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# convert the images to PIL format...
image = Image.fromarray(image)
gray_image = Image.fromarray(gray) ### save the gray image
# ...and then to ImageTk format
image = ImageTk.PhotoImage(image)
gray = ImageTk.PhotoImage(gray_image) ### use 'gray_image' instead of 'gray'
if panelA is None or panelB is None:
panelA = tk.Label(image=image)
panelA.image = image
panelA.pack(side="left", padx=10, pady=10)
panelB = tk.Label(image=gray)
panelB.image = gray
panelB.pack(side="right", padx=10, pady=10)
else:
panelA.configure(image=image)
panelB.configure(image=gray)
panelA.image = image
panelB.image = gray
panelA = None
panelB = None
gray_image = None
bframe = tk.Frame(root)
bframe.pack(side="bottom", fill="both", expand="yes")
btn = tk.Button(bframe, text="Select an image",font=('arial',10,'bold'),bg="cyan", command=selectimage)
btn.config(height=5,width=15)
btn.pack(side="left", fill="x", expand=1)
### function to save the gray image
def save_image():
if gray_image:
# ask the filename to be used as the output
filename = fd.asksaveasfilename()
if filename:
gray_image.save(filename) # save the gray image
tk.Button(bframe, text="Save image", font="arial 10 bold", bg="gold", width=15, height=5, command=save_image).pack(side="left", fill="x", expand=1)
# kick off the GUI
root.mainloop()
You may want to create a postscript file :
canvas.postscript(file="file_name.ps", colormode='color')
then use Pillow to save the postscript file as a png :
from PIL import Image
myImage = Image.open("file_name.ps")
myImage.save('imageName.png', 'png')

tkinter - When resizing color image, it shows up in red scale only

I have the following piece of code:
from tkinter import *
from tkinter import filedialog
from PIL import Image, ImageTk
import cv2
import os
import glob
import numpy as np
image_path = ""
image_list = []
class Proj:
def __init__(self, master):
self.master = master
#GUI height and width
w = 1250
h = 600
# open folder manager to select image folder
image_path = filedialog.askdirectory()
master.geometry("%dx%d%+d%+d" % (w ,h ,0,0))
master.resizable(True,True)
#read in images from folder
self.read_images(master, image_path)
#cv2.imshow('image',cv2.imread(image_list[0], 1))
self.img = cv2.imread(image_list[0])
self.img = Image.fromarray(np.array(self.img).copy())
self.img.thumbnail((w//2, w//2+10))
self.img = ImageTk.PhotoImage(self.img)
image_frame = Frame(master)
image_frame.grid(row = 0, column = 0, columnspan = 3, rowspan = 5)
left_panel = Canvas(image_frame, width=w//2, height=h-70)
left_panel.grid(row=0, column=0, columnspan=4)
imgA_handler = left_panel.create_image((0,0), image = self.img, anchor="nw")
right_panel = Canvas(image_frame, width=w//2, height=h-70)
right_panel.grid(row=0, column=5, columnspan=4)
def read_images(self, master, path):
images = path + '/*.tif'
for img in glob.glob(images): #will only read in tif images
image_list.append(img)
root = Tk()
example = Proj(root)
root.mainloop()
I am reading in color .tif images and then trying to display them in the left_panel. However, when I go to do that, it shows the normal color image only in red scale even though I never extracted just the red signal. I am completely unable to diagnose the issue. How do I fix this issue?
Ultimately, what I want to do is display two images on this GUI. An original image on the left and a modified image on the right. Currently my gui layout is set up as I've coded above. However, if you think there is an easier way to do this, then I'd be interested to hear.
This is because opencv uses BGR instead of RGB. When you are using this line: self.img = Image.fromarray(np.array(self.img).copy()) Blue and Red colors are being swapped. Just before you use the above code, convert the BGR to RGB in opencv and you should be good to go.
self.img = cv2.cvtColor(self.img,cv2.COLOR_BGR2RGB)
I see you are using opencv. Why don't you use the opencv command to resize.
It is very simple and works pretty well.
Take a look at this page:
OpenCV Resize
This is an example to make a image 50% smaller, or instead of the fx and fy, you can put the exact size you want.
thumbnail = cv2.resize(image, (0,0), fx=0.5, fy=0.5)

Tkinter, overlay foreground image on top of a background image with transparency

I have 2 images, in png format.
The second image, is a shape with transparent background.
First image:
Second image:
I cannot make the second image on top of the first at given coordinates (x,y) with the first image visible through the transparent zone of the second image.
Result desired:
import Tkinter
import Image, ImageTk
# open an image
head = Image.open('background2.png')
hand = Image.open('foreground2.png')
root = Tkinter.Tk() # A root window for displaying objects
head.paste(hand,(20,20))
# Convert the Image object into a TkPhoto object
tkimage = ImageTk.PhotoImage(head)
root.mainloop() # Start the GUI
An empty tk window is displayed.
Thanks Bryan.
Got it, in addition to label, the issue of transparency resolved from another question here (same foregound image used as a mask)
I guess, this is what cost me -2 points :-|
Now it works as expected.
from Tkinter import *
import Tkinter
from PIL import Image, ImageTk
root = Tkinter.Tk() # A root window for displaying objects
# open image
imageHead = Image.open('head.png')
imageHand = Image.open('hand.png')
imageHead.paste(imageHand, (20, 40), imageHand)
# Convert the Image object into a TkPhoto object
tkimage = ImageTk.PhotoImage(imageHead)
panel1 = Label(root, image=tkimage)
panel1.grid(row=0, column=2, sticky=E)
root.mainloop() # Start the GUI
Hey guys I know that I am 6 years late but I can help you with this
from PIL import Image
import numpy as np
# Create Image
img = Image.open("forground.png")
background = Image.open("background.png")
background.paste(img, (0, 0), img)
background.save('NewImg.png',"PNG")
NewImg = Image.open('NewImg.png')
# Use Image
tkimage = ImageTk.PhotoImage(NewImg)
panel1 = Label(root, image=tkimage)
panel1.grid(row=0, column=2, sticky=E)
root.mainloop() # Start the GUI
So all you have to do is use NewImg when dealing with the file.
This code creates an image out of the two images and then utilises that image in the program.

Categories