How can I remove blur / blur and rotate at the same time?

Viewed 154

I am a beginner in python and learning about PIL and tkinter.

Now what I am trying is to edit a image and I am struggling from blur and rotate.

When I blur an image, I cannot get rid of it without rotating it. (I want to make a button to on/off blur)

And if I blur/rotate an image, Another one doesn't work at the same time.

How can I solve this problem? here is my code

import tkinter as tk
from PIL import Image, ImageTk, ImageFilter
from tkinter import filedialog as fd

img=None
tk_img=None
angle=0

def open():
    global img, tk_img
    filename=fd.askopenfilename()
    img=Image.open(filename)
    tk_img=ImageTk.PhotoImage(img)
    canvas.create_image(250,250,image=tk_img)
    window.update()

def quit():
    window.destroy()

def image_rotate():
    global img,tk_img,angle
    angle=angle+45
    tk_img=ImageTk.PhotoImage(img.rotate(angle))
    canvas.create_image(250,250,image=tk_img)
    window.update()

def image_blur():
    global img,tk_img
    tk_img=ImageTk.PhotoImage(img.filter(ImageFilter.BLUR))
    canvas.create_image(250,250,image=tk_img)
    window.update()
    

window = tk.Tk() #윈도우 생성
canvas=tk.Canvas(window,width=500,height=500)
canvas.pack()

menubar = tk.Menu(window) #메뉴바 생성

filemenu = tk.Menu(menubar) #파일메뉴를 메뉴바에 달아줌 
filemenu.add_command(label="picture", command=open)
filemenu.add_command(label="exit", command=quit)
menubar.add_cascade(label="파일", menu=filemenu)

imagemenu=tk.Menu(menubar)
imagemenu.add_command(label="rotate",command=image_rotate)
imagemenu.add_command(label="blur",command=image_blur)
menubar.add_cascade(label="movement", menu=imagemenu)

window.config(menu=menubar)
window.mainloop()
2 Answers

The reason is quite obvious, your img object as seen is only defined/updated in open(), so the image will always refer to the original image selected and not the new edited image, so to show the change store it in a new variable and then globalize it.

Also note that you are creating a new canvas image every time you call the function, which is not efficient, so make a single canvas image and then update it each time, inside the function using itemconfig() method.

def open():
    global img, tk_img

    filename = fd.askopenfilename()
    img = Image.open(filename)
    tk_img = ImageTk.PhotoImage(img)
    canvas.itemconfig('img',image=tk_img) # Update image

def image_rotate():
    global tk_img, angle, img

    angle += 45 # More pythonic to always use += rather than a = a + 10
    img = img.rotate(angle)
    tk_img = ImageTk.PhotoImage(img)
    canvas.itemconfig('img',image=tk_img) # Update image
    angle -= 45

def image_blur():
    global tk_img, img

    img = img.filter(ImageFilter.BLUR)
    tk_img = ImageTk.PhotoImage(img)
    canvas.itemconfig('img',image=tk_img) # Update image
    

canvas = tk.Canvas(window,width=500,height=500)
canvas.create_image(250,250,tag='img') # Create initial canvas object
canvas.pack()

Also take a look at how I formatted your code to make it look more near, follow PEP 8 -- Style Guide for Python Code for more.

You can blur the image using opencv package

import cv2 
  

img = cv2.imread('imagepath') 
  
blurImg = cv2.blur(img,(10,10)) 
cv2.imshow('blurred image',blurImg)
  
cv2.waitKey(0)
cv2.destroyAllWindows()

Or u can check the documentation of opencv to blurr the image. U can also rotate image using opencv

# importing cv2
import cv2

src = cv2.imread(path)
window_name = 'Image'
image = cv2.rotate(src, cv2.ROTATE_90_COUNTERCLOCKWISE)
  # Displaying the image
cv2.imshow(window_name, image)
cv2.waitKey(0)

Related