Dom807
Dom807

Reputation: 37

There is an error although I followed documentation

from PIL import Image
from tkinter import *

def wider():
    global photo,lbpic
    pic = photo.get()
    adj = Image.open(pic)
    width,height = adj.size
    new_pic = adj.resize((width*2,height))
    new_pic.save('Wider'+pic)
    lbpic['image'] = new_pic
    lbpic.image = new_pic

def taller():
    global photo,lbpic
    pic = photo.get()
    adj = Image.open(pic)
    width,height = adj.size
    new_pic = adj.resize((width,height*2))
    new_pic.save('Taller'+pic)
    lbpic['image'] = new_pic
    lbpic.image = new_pic

def rotateangle():
    global photo,lbpic,var
    pic = photo.get()
    adj = Image.open(pic)
    angle = var.get()
    result = adj.rotate(angle)
    result.save('rotated'+angle+pic)
    lbpic['image'] = result
    lbpic.image = result

def rotate():
    global photo,lbpic
    var = StringVar()
    var.set(90)
    rb1 = Radiobutton(win,text='90',variable=var,value=90,command=rotateangle)
    rb1.place(x=100,y=110)
    rb2 = Radiobutton(win,text='180',variable=var,value=180,command=rotateangle)
    rb2.place(x=100,y=140)
    rb3 = Radiobutton(win,text='270',variable=var,value=270,command=rotateangle)
    rb3.place(x=100,y=170)
    
    
win = Tk()
win.title('Photo adjust')
win.geometry('400x400')

lb = Label(win,text='Select a photo')
lb.place(x=100,y=20)

photo = StringVar()
en = Entry(win,textvariable=photo,width=30)
en.place(x=100,y=50)

btn = Button(win,text='Wider',command=wider)
btn.place(x=100,y=80)

btn2 = Button(win,text='Taller',command=taller)
btn2.place(x=150,y=80)

btnrotate = Button(win,text='Rotate',command=rotate)
btnrotate.place(x=200,y=80)

lbpic = Label(win,image='')
lbpic.place(x=150,y=200)

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python38\lib\tkinter\__init__.py", line 1883, in __call__
    return self.func(*args)
  File "E:/Python/Python Projects Fun/photo_shop.py", line 7, in wider
    adj = Image.open(pic)
AttributeError: type object 'Image' has no attribute 'open'

For this program, I would like to select a picture to change different effects within the buttons. However I am not able to open image by using Image.open(pic) but I have already checked thoroughly the documentation that Image module has open method. I followed the documentation but I do not understand where is the problem? Or the version problem?

Upvotes: 1

Views: 51

Answers (1)

P S Solanki
P S Solanki

Reputation: 1123

This works on Windows::

solution 1

import tkinter as tk
from PIL import ImageTk, Image


root = tk.Tk()

myImage = ImageTk.PhotoImage(Image.open('test.png'))  # your image here

# you can do anything with that image object now.
# You can get all the common image formats (i used a png image)
# The PhotoImage object may not have attributes like PIL.Image 
# SO IN THAT CASE CHECK MY SECOND SOLUTION BELOW
#

tk.Label(root, image=myImage).pack()

root.mainloop()

Reason :

according to Your import statements (you have used global imports - also called wildcard imports), The Image object from tkinter library overrides Image object you imported from PIL.
Which makes it hard for the interpreter to know if you have really used PIL.Image or tkinter.Image.

*** That's why it is recommended to use import statements like this***

import tkinter as tk
from PIL import Image as Immmage # or whatever name you prefer
import tkinter.messagebox as msgb
from pyautogui import size

Solution 2 (For your needs)

You own code may even work if you change your import style.

from PIL import Image as someThingElse  # your choice again
from tkinter import *   # again global import not recommended but only if you need so

def wider():
    global photo,lbpic
    pic = photo.get()
    adj = someThingElse.open(pic)
    width,height = adj.size
    new_pic = adj.resize((width*2,height))
    new_pic.save('Wider'+pic)
    lbpic['image'] = new_pic
    lbpic.image = new_pic

def taller():
    global photo,lbpic
    pic = photo.get()
    adj = someThingElse.open(pic)
    width,height = adj.size
    new_pic = adj.resize((width,height*2))
    new_pic.save('Taller'+pic)
    lbpic['image'] = new_pic
    lbpic.image = new_pic

def rotateangle():
    global photo,lbpic,var
    pic = photo.get()
    adj = someThingElse.open(pic)
    angle = var.get()
    result = adj.rotate(angle)
    result.save('rotated'+angle+pic)
    lbpic['image'] = result
    lbpic.image = result

def rotate():
    global photo,lbpic
    var = StringVar()
    var.set(90)
    rb1 = Radiobutton(win,text='90',variable=var,value=90,command=rotateangle)
    rb1.place(x=100,y=110)
    rb2 = Radiobutton(win,text='180',variable=var,value=180,command=rotateangle)
    rb2.place(x=100,y=140)
    rb3 = Radiobutton(win,text='270',variable=var,value=270,command=rotateangle)
    rb3.place(x=100,y=170)
    
    
win = Tk()
win.title('Photo adjust')
win.geometry('400x400')

lb = Label(win,text='Select a photo')
lb.place(x=100,y=20)

photo = StringVar()
en = Entry(win,textvariable=photo,width=30)
en.place(x=100,y=50)

btn = Button(win,text='Wider',command=wider)
btn.place(x=100,y=80)

btn2 = Button(win,text='Taller',command=taller)
btn2.place(x=150,y=80)

btnrotate = Button(win,text='Rotate',command=rotate)
btnrotate.place(x=200,y=80)

lbpic = Label(win,image='')
lbpic.place(x=150,y=200)

Upvotes: 1

Related Questions