I'm trying to rotate an image using Pillow:
img = Image.open("./assets/aircraftCarrier/aircraftCarrier0.gif")
img = img.rotate(270)
This rotates the image but when I try to save it Pillow doesn't seem to recognise the file type, even if I put the format type when saving it:
img.save("./tempData/img", "GIF")
It comes up with a file with a blank extension
Now this doesn't really matter as long as tkinter can recognise it with PhotoImage, but that doesn't seem to work either:
img = PhotoImage(img)
label = Label(root, image=img)
label.pack()
I get this error message:
TypeError: __str__ returned non-string (type Image)
I'm not really sure what I've done wrong or if I need to do more processing with Pillow.
Help would be greatly appreciated,
Josh
Full code:
import tkinter as tk
from tkinter import *
import tkinter
from PIL import Image
root = tk.Tk()
root.title("Test")
img = Image.open("./assets/aircraftCarrier/aircraftCarrier0.gif")
img = img.rotate(270)
img.save("./tempData/img", "GIF")
img = PhotoImage(img)
label = Label(root, image=img)
label.pack()
root.mainloop()
Full error message:
Traceback (most recent call last):
File "C:\Users\Joshlucpoll\Documents\Battleships\test.py", line 19, in <module>
label = Label(root, image=img)
File "C:\Users\Joshlucpoll\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 2766, in __init__
Widget.__init__(self, master, 'label', cnf, kw)
File "C:\Users\Joshlucpoll\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 2299, in __init__
(widgetName, self._w) + extra + self._options(cnf))
TypeError: __str__ returned non-string (type Image)
Ok, looking into the effbot documentation for PhotoImage there are these lines of code:
from PIL import Image, ImageTk
image = Image.open("lenna.jpg")
photo = ImageTk.PhotoImage(image)
and it states:
If you need to work with other file formats, the Python Imaging
Library (PIL) contains classes that lets you load images in over 30
formats, and convert them to Tkinter-compatible image objects
So it seems you need to add ImageTk before PhotoImage when converting from PIL to Tkinter.
Eg:
img = ImageTk.PhotoImage(img)
Adding this to my program does result in the rotated image to show perfectly.
Related
I want to show a .tif file in a tkinter gui, but I have been having trouble getting the images to load properly. I was able to view the image correctly using Image.open with mode='r', but then when I call ImageTk.PhotoImage it displays a blank white canvas. Here is the code:
def func(image_paths):
root = Tk()
im = Image.open(image_paths[0], mode='r')
im.show() # shows image correctly
im = ImageTk.PhotoImage(im)
im_label = Label(image=im)
# im_label = Label(image=ImageTk.PhotoImage(Image.open(image_paths[0], mode='r'))) # This doesn't work either
im_label.grid(row=0, column=0, columnspan=3)
root.mainloop()
Any help is much appreciated!
So, what ended up working was the solution in this video: https://www.youtube.com/watch?v=6l6HDQyWdH0
The lines of code that got it to work was:
curr = Image.open(image_paths[0], mode='r')
curr = Image.fromarray(np.uint8(cm.jet(NormalizeData(np.array(curr).astype(np.float64)))*255))
curr = ImageTk.PhotoImage(curr)
i am a beginner of python programming.i will place the images on the frame. but image not not diaplayed error shown below.
Traceback (most recent call last):
File "C:/Users/kobinath/PycharmProjects/pythonProject4/jj.py", line 5, in <module>
img = PhotoImage(file="pic.jpg")
File "C:\Users\kobinath\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 4061, in __init__
Image.__init__(self, 'photo', name, cnf, master, **kw)
File "C:\Users\kobinath\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 4006, in __init__
self.tk.call(('image', 'create', imgtype, name,) + options)
_tkinter.TclError: couldn't recognize data in image file "pic.jpg"
what i tried so far i attached below.
from tkinter import *
root = Tk()
canvas = Canvas(root, width = 600, height = 600)
canvas.pack()
img = PhotoImage(file="pic.jpg")
canvas.create_image(20,20, anchor=NW, image=img)
root.mainloop()
I actually think its not possible to use jpg with PhotoImage directly, instead you might want to use PIL and heres how,
pip install PIL
After this, just say
from tkinter import *
from PIL import Image,ImageTk
root = Tk()
canvas = Canvas(root, width = 600, height = 600)
canvas.pack()
img_file = Image.open("sad songs.jpg")
img_file = img_file.resize((150,150)) #(width,height)
img = ImageTk.PhotoImage(img_file)
canvas.create_image(20,20, anchor=NW, image=img)
root.mainloop()
Here is a site to convert jpg to gif
Do let me know, if any errors or doubts
Cheers
It may be a result of a new bug thats been going on with tkinter images where we have to keep a reference of the image to make sure it will work I hope this will fix it.
canvas.img = img
Also as #Cool Cloud has also pointed out it can also be the problem where it does not work with jpg files sometimes but for me sometimes it does too, so if its not working with you, you can just convert it into a png or gif(I would prefer png based on what has worked with me when I ran into these problems).
Also instead of the conversion you can try the PIL library it can be installed using
pip install PIL
And then you can use a class called PhotoImage(yup it has the same name as the tkinter class) to do the image loading and stuff, which is under the module ImageTk which can be used to deal with tkinter images.
Also you can pass the image object into this class as a parameter, you can create an Image object like so-:
img_obj = Image.open('annoying_image.jpg') # uses the Image module from PIL use import PIL.Image
Like so
img = PIL.ImageTk.PhotoImage(img_obj) # uses the Image module from PIL use import PIL.ImageTk
Also If you want to know more about PIL, its just basically a Image Processing Library of python often called as pillow also.
IMPORT STATEMENTS(JUST IN CASE ITS NOT CLEAR)
from PIL import Image, ImageTk
Good day, I am quite new to Python programming and I was tasked to do my own GUI with image inside my GUI. I have been doing some good progress but i was stuck when I want to insert an image into my GUI from my webcam. However, I did manage to get an image from the webcam but it has to be a different window with the GUI window.
In my GUI codes, it includes a simple code like this:
(I use range i<25 because my webcam needs warming up)
for i in range (25):
_ , frame = cap.read()
frame = cv2.flip(frame, 1)
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
i+=1
cv2.imshow("Latex Truck", cv2image)
img = cv2image
label = Label(root, image = img)
label.place(x = 300, y = 300)
Now, the problem is this. I successfully obtain the frame that I need and was able to show thanks to cv2.imshow but when I try to use the same source which is the "cv2image" in tkinter, it shows this error.
Traceback (most recent call last):
File "C:\Python34\lib\tkinter\__init__.py", line 1487, in __call__
return self.func(*args)
File "C:\Users\FF7_C\OneDrive\Desktop\Logo.py", line 82, in Capture
label = Label(root, image = img)
File "C:\Python34\lib\tkinter\__init__.py", line 2573, in __init__
Widget.__init__(self, master, 'label', cnf, kw)
File "C:\Python34\lib\tkinter\__init__.py", line 2091, in __init__
(widgetName, self._w) + extra + self._options(cnf))
_tkinter.TclError: image "[[[ 49 32 22 255]
Now, logically I think I did what I needed to do which is the extract an image from the webcam which I did, the only problem now is I need to understand why tkinter cannot read the same information read by cv2.imshow.
Can someone guide me on this? Thank you very much! :)
The format returned by cv2.cvtColor(...) is of type numpy.ndarray. You need to convert it to format recognized by tkinter by using Pillow module:
from tkinter import *
from PIL import Image, ImageTk
import cv2
root = Tk()
cap = cv2.VideoCapture(0)
ret, frame = cap.read()
img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
# convert to image format recognized by tkinter
img = Image.fromarray(img)
tkimg = ImageTk.PhotoImage(image=img)
Label(root, image=tkimg).pack()
root.mainloop()
I am trying to do some video stream from my raspberry pi over the wifi. I used pygame, because i also have to use gamepad in my project. Unfortunately I stucked on displaying received frame. Shortly: i get jpeg frame, open it with PIL, convert to string - after that i can load image from string
image_stream = io.BytesIO()
...
frame_1 = Image.open(image_stream)
f = StringIO.StringIO()
frame_1.save(f, "JPEG")
data = f.getvalue()
frame = pygame.image.fromstring(frame_1,image_len,"RGB")
screen.fill(white)
screen.blit(frame, (0,0))
pygame.display.flip()
and error is :
Traceback (most recent call last):
File "C:\Users\defau_000\Desktop\server.py", line 57, in <module>
frame = pygame.image.fromstring(frame_1,image_len,"RGB")
TypeError: must be str, not instance
Sloth's answer is incorrect for newer versions of Pygame. The tostring() definition is deprecated. Here is a working variant for Python 3.6, PIL 5.1.0, Pygame 1.9.3:
raw_str = frame_1.tobytes("raw", 'RGBA')
pygame_surface = pygame.image.fromstring(raw_str, size, 'RGBA')
The first argument to pygame.image.fromstring has to be a str.
So when frame_1 is your PIL image, convert it to a string with tostring, and load this string with pygame.image.fromstring.
You have to know the size of the image for this to work.
raw_str = frame_1.tostring("raw", 'RGBA')
pygame_surface = pygame.image.fromstring(raw_str, size, 'RGBA')
I am using python( my version is 2.7 ). I want to add an image to GUI (Tkinter) and then convert into executable format using pyinstaller.
I did followed as on SO, and also as said on ActiveState
When i mention the image's path on the code, it works only if i run it directly. If i convert it to exe it doesnt open.
Changing the code as mentioned from other solutions, like by converting it into encoded string, it runs fine on linux. But on windows it throws error
code:
from Tkinter import *
from PIL import ImageTk, Image
logo = '''
----- encoded string -----
'''
root = Tk()
logoimage = Tkinter.PhotoImage(master=root, data=logo)
Label(root, image=logoimage).pack()
root.mainloop()
Change 1:
The above code works on linux. On windows i get error on the line logoimage = Tkinter.PhotoImage(master=root, data=logo) as
NameError: name 'Tkinter' is not defined
Change 2:
So i tries changing the line as logoimage = ImageTk.PhotoImage(master=root, data=logo). The error i get is
File "C:\Python27\lib\site-packages\PIL\ImageTk.py", line 88, in __init__
image = Image.open(BytesIO(kw["data"]))
File "C:\Python27\lib\site-packages\PIL\Image.py", line 2330, in open
% (filename if filename else fp))
IOError: cannot identify image file <_io.BytesIO object at 0x00000000024BB150>
Exception AttributeError: "'PhotoImage' object has no attribute '_PhotoImage__photo'" in <bound method PhotoImage.__del__ of <PIL.ImageTk.PhotoImage object at 0x00000000024D49E8>> ignored
Change 3:
But, if i change the line as iconImage= ImageTk.PhotoImage(Image.open('path_to_image.png')). It works only if i run directly. If i convert it to executable, then console opens for 2-3 seconds and displaying error something like Unable to locate the image file
Doing the decoding and converting explicitly may be more robust than what you're currently doing. This code works on Python 2.6.6 on Linux.
import io, base64
from Tkinter import *
from PIL import ImageTk, Image
#A simple 64x64 PNG fading from orange in the top left corner
# to red in the bottom right, encoded in base64
logo_b64 = '''
iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAIA
AAAlC+aJAAAA/0lEQVR4nO3Zyw7CMAxEUdP//+W2rCqBoJA2noclS1kn9yjLeex7xKY76+
wNS+l6KSCjXgdIqhcB8uoVgNR6OiC7ngsA1BMBmHoWAFZPASDr8QBwPRiAr0cCKPUwAKse
AyDWAwDc+mwAvT4VoKjPA4jqkwC6+gyAtD7WSYC6fu4HDOonAB71dwE29bcATvXXAWb1Fw
F+9VcAlvXDANf6MYBx/QDAu/4fwL7+J6BC/TmgSP0JoE79N0Cp+g9Atfp3QMH6F0DN+gNQ
tj62WErXB2PgQNZLAb3U6wC91OsAvdTrAL3U6wC91OsAvdTrAL3U6wC91OsAvdTrAL3Uz7
z+BNmX4gqbppsaAAAAAElFTkSuQmCC
'''
#Decode the PNG data & "wrap" it into a file-like object
fh = io.BytesIO(base64.b64decode(logo_b64))
#Create a PIL image from the PNG data
img = Image.open(fh, mode='r')
#We must open the window before calling ImageTk.PhotoImage
root = Tk()
photo = ImageTk.PhotoImage(image=img)
Label(root, image=photo).pack()
Label(root, text='An embedded\nbase64-encoded PNG').pack()
root.mainloop()
For reference, here's what that embedded PNG looks like.
from Tkinter import *
#...
logoimage = Tkinter.PhotoImage(master=root, data=logo)
If you dump the Tkinter module straight into the global scope using import *, then you shouldn't prefix class and function names with the module name. Either remove the prefix, or remove the import *.
import Tkinter
#...
logoimage = Tkinter.PhotoImage(master=root, data=logo)
Or
from Tkinter import *
#...
logoimage = PhotoImage(master=root, data=logo)
I suspect you're not getting the error in Linux because your version of Python imports common modules automatically. Effectively, there's an invisible import Tkinter at the top of all your scripts.