Im using PIL and TKinter to open an image. I do not understand why I'm getting this error
import os
import random
from PIL import Image
import time
from tkinter import *
root = Tk()
def timer(mins):
time.sleep(mins * 60)
def anmuViewer():
random_pic = (random.choice(os.listdir("D:/de_clutter/memez/anmu")))
openPic = Image.open('D:/de_clutter/memez/anmu/' + random_pic)
openPic.show()
timer(3)
start_btn = Button(root, text = "Start", command = anmuViewer)
start_btn.pack()
root.mainloop()
what should happen is a tkinter window should pop up with only a button called "start". When I click that button, a new window with the image should pop up. instead I get this error
line 17, in anmuViewer
openPic = Image.open('D:/de_clutter/memez/anmu/' + random_pic)
AttributeError: type object 'Image' has no attribute 'open'
Like Michael Butscher said,
"tkinter.Image" overwrites "PIL.Image" in your module's namespace. Avoid imports with *
But if you must use a wildcard import, importing tkinter before PIL should solve your problem
from tkinter import *
import os
import random
from PIL import Image
import time
Related
I'm trying to make an interface using tkxui and tkinter for the modules it doesn't cover (Label, anchors etc)
from urllib.request import urlopen
from PIL import Image, ImageTk
from io import BytesIO
from tkinter import *
import tkxui
win = tkxui.Tk(display=tkxui.FRAMELESS, defaultBorder=True)
win.geometry("700x400")
win.title("Window Title")
win.minsize(700, 400)
win.center()
URL = "http://www.universeofsymbolism.com/images/ram-spirit-animal.jpg"
u = urlopen(URL)
raw_data = u.read()
u.close()
im = Image.open(BytesIO(raw_data))
photo = ImageTk.PhotoImage(im)
When running this code I get AttributeError: type object 'Image' has no attribute 'open'(line 18) as Traceback. It seems like tkinter and PIL are overlapping with the open function.
How can I avoid this?
Solved by importing the needed tkinter modules like this:
from tkinter.constants import *
and
from tkinter import Label
for some reason, Tkinter can't open my image. If I don't add from tkinter import * it shows error message as:
Error Message without from tkinter import *:
C:\Users\NG>python e:/PythonTkinter/app.py
Traceback (most recent call last):
File "e:/PythonTkinter/app.py", line 12, in <module>
logo = Image.open('logo.png')
File "C:\Users\NG\anaconda3\lib\site-packages\PIL\Image.py", line 2891, in open
fp = builtins.open(filename, "rb")
FileNotFoundError: [Errno 2] No such file or directory: 'logo.png'
and if I add from tkinter import * as shown below, it shows error message as shown below.
Code:
import tkinter as tk
import PyPDF2
from PIL import Image, ImageTk
from tkinter import *
# begaining of our UI window
root = tk.Tk()
canvas = tk.Canvas(root, width=600, height=300)
canvas.grid(columnspan=3)
# Adding logo
# logo = ImageTk.PhotoImage(Image.open("logo.png"))
logo = Image.open("logo.png")
logo = ImageTk.PhotoImage(logo)
logo_label = tk.Label(image=logo)
loogo_label.image = logo
logo_label.grid(column=1, row=0)
# ending of our UI window
root.mainloop()
Error Message with from tkinter import *:
C:\Users\NG>python e:/PythonTkinter/app.py
Traceback (most recent call last):
File "e:/PythonTkinter/app.py", line 14, in <module>
logo = Image.open("logo.png")
AttributeError: type object 'Image' has no attribute 'open'
Image is right there in same folder where this python file is.
WHAT AM I DOING WRONG ? HELP!
Explanation:-
You should probably understand what relative path is. When relative path is used, it is not relative the location of the python file, but instead the location from where you are running the python file. Here you are running the file from:
C:\Users\NG
But your python file and the image you are using is inside:
e:/PythonTkinter/app.py
Solution:-
So here either you can change the location from where you're running the code to the location with image file OR you can copy the image to the location you are running the py file from(i.e., 'C:\Users\NG').
And as far as the second error is concerned, it's never a good idea to say from x import *. When you import '*' from tkinter, it replaces the PIL.Image with tkinter.Image. And hence the error. So either remove that line or move it to the top most. Recommended import is:
import tkinter as tk
import PyPDF2
from PIL import Image, ImageTk
You are just using the first import here, so I don't see a point in using from tkinter import *, so just remove it.
You can simply do as follows
from tkinter import *
window = Tk() # instantiate an instance of a window for us
window.geometry("500x500")
#creating a photo image from png photo
icon = PhotoImage(file='GUI using Python\\flower.png')
window.iconphoto(True, icon)
window.mainloop()
starting from the comment (creating a photo image from png photo), you give a value in the file parameter the relative path not the full path, also take care of the backslash, you should write two backslashes and no need for all of these libraries that you are using unless you are counting on them for other tasks.
Your PIL import should be after 'from tkinter import *'. Also make sure to be in the same directory as the image
I am trying to build a program which gets me an enlarged photo of the text I want, for this I decided to use tkinter, win32gui and pygetwindow modules after taking some tips from already asked problems on stack overflow am having the following problems:
(1)I don't know how to get the hwnd value of the tkinter window which I created.
(2)I can't get hwnd value even if I know how to get it as the window is created after the complete code has run.
So please suggest me solutions to the problem
This is my code:
from tkinter import *
import win32gui
import pygetwindow as gw
#making the tkinter window
root = Tk()
root.title('DaysLeft')
#getting all the windows with their hwnd values
hwnd=gw.getAllWindows()
print(hwnd)
win32gui.SetForegroundWindow(hwnd)
bbox = win32gui.GetWindowRect(hwnd)
img = ImageGrab.grab(bbox)
img.show()
mainloop()
The above code gives error below as expected:.
line 26, in <module>
win32gui.SetForegroundWindow(hwnd)
TypeError: The object is not a PyHANDLE object
You can use PIL for taking a screenshot and win32gui or pygetwindow to get windows location.
Install PIL by saying
pip install Pillow
then your working code would be:
from tkinter import *
from win32gui import FindWindow, GetWindowRect
import pygetwindow as gw
from PIL import ImageGrab
def ss():
win = gw.getWindowsWithTitle('DaysLeft')[0]
winleft = win.left+9
wintop = win.top+38 #change 38 to 7 to not capture the titlebar
winright = win.right-9
winbottom = win.bottom-9
final_rect = (winleft,wintop,winright,winbottom)
img = ImageGrab.grab(final_rect)
img.save('Required Image.png')
#making the tkinter window
root = Tk()
root.title('DaysLeft')
root.after(3000,ss)
root.mainloop()
Why am i subtracting some amount from the pixels? its because, windows has decorations like drop shadow effect to the windows, which are also part of the windows and will be included in the screenshot, so i used this to get rid of those extra pixels.
Or if your still reluctant on using win32gui then, change the function to:
from win32gui import FindWindow, GetWindowRect
from PIL import ImageGrab
......
def ss():
win = FindWindow(None, 'DaysLeft')
rect = GetWindowRect(win)
list_rect = list(rect)
list_frame = [-9, -38, 9, 9] #change -38 to -7 to not capture the titlebar
final_rect = tuple((map(lambda x,y:x-y,list_rect,list_frame))) #subtracting two lists
img = ImageGrab.grab(bbox=final_rect)
img.save('Image.png')
What is after method? It just calls the function after 3000 ms, i.e, 3 seconds. We are basically giving the system some time to build the GUI and capture screenshot.
Hope it helped, do let me know if any errors or doubts.
Cheers
I created a simple image opening program which opens the image selected from filedialog by clicking a button, but wherever I select another image it just appears under the current image
I want the next image selected to be replaced by the old image.
Plz help what should I do
from tkinter import *
from PIL import Image,ImageTk
from tkinter import filedialog
root=Tk()
root.title('Image')
def open():
global my_img
root.filename = filedialog.askopenfilename(initialdir='/GUI',title='Select A File',filetypes=(('jpg files','*.jpg'),('png files','*.png'),('all files','*.*')))
my_img = ImageTk.PhotoImage(Image.open(root.filename))
my_image_lbl = Label(image=my_img).pack()
my_btn = Button(root,text='Open File Manager',command=open).pack()
root.mainloop()
You should create the my_image_lbl outside open() and update its image inside the function:
from tkinter import *
from PIL import Image,ImageTk
from tkinter import filedialog
root=Tk()
root.title('Image')
def open():
filename = filedialog.askopenfilename(initialdir='/GUI',title='Select A File',filetypes=(('jpg files','*.jpg'),('png files','*.png'),('all files','*.*')))
if filename:
my_image_lbl.image = ImageTk.PhotoImage(file=filename)
my_image_lbl.config(image=my_image_lbl.image)
Button(root,text='Open File Manager',command=open).pack()
my_image_lbl = Label(root)
my_image_lbl.pack()
root.mainloop()
I am trying to pass the path of an image and then opening it but i get this error for this line image = Image.open(path):
AttributeError: type object 'Image' has no attribute 'open'
from PIL import Image
from tkinter import *
class Menu:
def __init__(self,root):
self.root = root
self.root.title("Image")
self.image_entry = Entry(root)
self.image_entry.grid(row=0,column=1)
image_label = Label(root,text = "Enter the path of the image").grid(row=0)
images = Button(root,text="Show",command=lambda:[self.show(self.image_entry)]).grid(row=1,column=1)
root.mainloop()
def show(self,image_entry):
path=image_entry.get()
image = Image.open(path)
image.show()
The variable Image imported from PIL is being overwritten by the variable Image imported from Tkinter.
Possible solutions, in descending order of best-practice-ness:
Don't import things from tkinter using import *. Try importing only the names you need, for example from tkinter import Entry, Label, Button, Tk.
Choose an alias for PIL's Image that doesn't conflict with Tkinter's Image. For example, from PIL import Image as PILImage.
Switch the order of your imports so PIL's Image overwrites Tkinter's Image, instead of the other way around.