tkinter: imagetk image in a canvas - python

I'm missing something simple here... I'm trying to insert an image in a canvas,
photoconn = Image.open(giffname)
photoconn = photoconn.resize((w0*self.resize/100,h*self.resize/100), Image.ANTIALIAS)
photoImg = ImageTk.PhotoImage(photoconn)
pc.append(photoImg)
self.cv.create_image(10, 10, anchor=NW, image=photoImg)
and I get the dreaded _tkinter.TclError: image "pyimage39" doesn't exist
Yet I memorize the image in the global pc array, and the debugger shows that the variables seem ok, with photoconn being a <PIL.GifImagePlugin.GifImageFile 0x260fab8; len=28>, and photoImg being a <PIL.ImageTk.PhotoImage 0x260fb48; len=12>.
... what am I missing?

Related

A buffer which shows in pygame does not display in tkinter

The code below illustrates a buffer which displays with pygame.image.frombuffer but not with tkinter PhotoImage
import chess, chess.svg, pylunasvg as pl
from tkinter import Tk, PhotoImage
# This is where I create the buffer
board = chess.Board(chess.STARTING_FEN)
svg_text = chess.svg.board(board, size=400)
document = pl.Document.loadFromData(svg_text)
byts = bytes(document.renderToBitmap())
#Now that I have this raster buffer 'byts'
surf = pygame.image.frombuffer(byt, (400, 400), 'RGBA') #works
root = Tk()
PhotoImage(data=byt) #raises an error about the image
I know this is as a result of something I don't know about tkinter. I would really appreciate that you point out what is wrong and what I can do.
Thanks in advance
PhotoImage's argument must be a file path. However, there is a solution using a PLI image. See Tkinter PhotoImage. Make a PLI image form the buffer and use that image to create an ImageTk.PhotoImage object:
from PIL import Image, ImageTk
image = Image.frombytes('RGBA', (400, 400), byt, 'raw')
root = Tk()
photo_image = ImageTk.PhotoImage(image)

Why does my PhotoImage doesn't shows up in tkinter?

it's my first question here.
I use tkinter with python3.9 for displaying an image, a flag of which country it shows up on the window
# gets the img flag
flag = PhotoImage(file=flagsFolder+countryList[rand_label]) # the path is "D:\Images\Flags of the world" + "XXXX.gif"
# creates the img Label
flagLabel = Label(frame, image=flag)
flagLabel.place(x=window_width/2, y=200, anchor='center')
So, when I try to display the image, it shows me this:
A flag should be here instead of the white image.
Why isn't it showing up?
So I messed around a bit and found out a solution.
I had to use ImageTk from Pillow so:
from PIL import ImageTk
Then, instead of creating a Label for my image, I made a Canvas:
# notice how I used ImageTk.PhotoImage instead of the basic PhotoImage from Tkinter
img = ImageTk.PhotoImage(file='filename.png')
# creates the img Canvas
imgCanvas = Canvas(frame)
imgCanvas.place(x=window_width/2, y=200, anchor='center', width=img.width(), height=img.height())
imgCanvas.create_image(0, 0, anchor=NW, image=img)
imgCanvas.image = img # now the image displays perfectly :D
The final result:

How to get rid of the resize attribute error?

I'd like to know if I did something wrong in my code or if I have to update something cause every single time I try to resize an image I have this: Attribute Error 'PhotoImage' object has no attribute 'resize'.
import tkinter as tk
from PIL import Image, ImageTk
image1 = Image.open("enseigne.JPEG")
image1= ImageTk.PhotoImage(image1)
imageresize = image1.thumbnail((500,500), Image.ANTIALIAS)
imageresize = ImageTk.PhotoImage(imageresize)
limage = tk.Label(app, image=imageresize)
The error means what it says, PhotoImage object does not have resize attribute, then what has? It is the Image object that has resize. You can remove your first PhotoImage(because it uses resize), as its no use:
image1 = Image.open("enseigne.JPEG")
imageresize = image1.thumbnail((500,500), Image.ANTIALIAS)
imageresize = ImageTk.PhotoImage(imageresize)
limage = tk.Label(app, image=imageresize)
If you want shorter code:
image1 = ImageTk.PhotoImage(Image.open("enseigne.JPEG").thumbnail((500,500), Image.ANTIALIAS))
limage = tk.Label(app, image=image1)
Obvious question: You are not calling resize but why are you getting such error? It is because thumbnail uses resize implicitly(based on conditions).

image doesn't show up on canvas output

I am trying to simply get some image on canvas, but even though I don't get any errors, my canvas stays white, no picture shows up. I know it will be some stupid misteak, but I can't find it.
def obrazek():
mesic = tkinter.PhotoImage(file="moon-0.gif")
canvas.create_image(700, 500, image = mesic)
rodic = tkinter.Tk()
rodic.title(u"Slunce a Měsíc")
rodic.geometry("+1000+300")
canvas = tkinter.Canvas(rodic, width=1400, height=800,)
canvas.pack()
obrazek()
tkinter.mainloop()
Output is whitescreen.
Keep a reference to the image by returning from the function
Then call pack() after the function obrazek

Resizing pictures in PIL in Tkinter

I'm currently using PIL to display images in Tkinter. I'd like to temporarily resize these images so that they can be viewed more easily. How can I go about this?
Snippet:
self.pw.pic = ImageTk.PhotoImage(Image.open(self.pic_file))
self.pw.pic_label = TK.Label(self.pw , image=self.pw.pic,borderwidth=0)
self.pw.pic_label.grid(column=0,row=0)
Here's what I do and it works pretty well...
image = Image.open(Image_Location)
image = image.resize((250, 250), Image.ANTIALIAS) ## The (250, 250) is (height, width)
self.pw.pic = ImageTk.PhotoImage(image)
There you go :)
EDIT:
Here is my import statement:
from Tkinter import *
import tkFont
from PIL import Image
And here is the complete working code I adapted this example from:
im_temp = Image.open(Image_Location)
im_temp = im_temp.resize((250, 250), Image.ANTIALIAS)
im_temp.save("ArtWrk.ppm", "ppm") ## The only reason I included this was to convert
## The image into a format that Tkinter woulden't complain about
self.photo = PhotoImage(file="ArtWrk.ppm") ## Open the image as a tkinter.PhotoImage class()
self.Artwork.destroy() ## Erase the last drawn picture (in the program the picture I used was changing)
self.Artwork = Label(self.frame, image=self.photo) ## Sets the image too the label
self.Artwork.photo = self.photo ## Make the image actually display (If I don't include this it won't display an image)
self.Artwork.pack() ## Repack the image
And here are the PhotoImage class docs: http://www.pythonware.com/library/tkinter/introduction/photoimage.htm
Note...
After checking the pythonware documentation on ImageTK's PhotoImage class (Which is very sparse) I appears that if your snippet works than this should as well as long as you import the PIL "Image" Library an the PIL "ImageTK" Library and that both PIL and tkinter are up-to-date. On another side-note I can't even find the "ImageTK" module life for the life of me. Could you post your imports?
if you don't want save it you can try it:
from Tkinter import *
from PIL import Image, ImageTk
root = Tk()
same = True
#n can't be zero, recommend 0.25-4
n=2
path = "../img/Stalin.jpeg"
image = Image.open(path)
[imageSizeWidth, imageSizeHeight] = image.size
newImageSizeWidth = int(imageSizeWidth*n)
if same:
newImageSizeHeight = int(imageSizeHeight*n)
else:
newImageSizeHeight = int(imageSizeHeight/n)
image = image.resize((newImageSizeWidth, newImageSizeHeight), Image.ANTIALIAS)
img = ImageTk.PhotoImage(image)
Canvas1 = Canvas(root)
Canvas1.create_image(newImageSizeWidth/2,newImageSizeHeight/2,image = img)
Canvas1.config(bg="blue",width = newImageSizeWidth, height = newImageSizeHeight)
Canvas1.pack(side=LEFT,expand=True,fill=BOTH)
root.mainloop()
the easiest might be to create a new image based on the original, then swap out the original with the larger copy. For that, a tk image has a copy method which lets you zoom or subsample the original image when making the copy. Unfortunately it only lets you zoom/subsample in factors of 2.

Categories

Resources