I have created a short script to display a photo in a Tkinter canvas element. I size the canvas element to have the same size as the photo, but when I launch the window, I generally only see a small portion of the image, no matter how much I expand the window.
Also when I print out the size of the image, which I am using to set the size of the canvas, this size says (922, 614) whereas when I record mouse clicks on the canvas, the lower-right hand corner is at something like (500, 300). My code is below. What should I change so that the canvas is the same size as the image and fully shows the image?
class AppWindow(Frame):
def __init__(self, parent, list_of_files, write_file):
Frame.__init__(self, parent)
self.parent = parent
...
self.image = None
self.canvas = None
self.index = -1
self.loadImage()
self.initUI()
self.resetCanvas()
def initUI(self):
self.style = Style()
self.style.theme_use("default")
self.pack(fill=BOTH, expand=1)
...
self.canvas = Tkinter.Canvas(self, width = self.image.width(), height = self.image.height())
def loadImage(self):
self.index += 1
img = cv2.imread(self.list_of_files[self.index])
img = cv2.resize(img, (0,0), fx = IMAGE_RESIZE_FACTOR, fy = IMAGE_RESIZE_FACTOR)
b, g, r = cv2.split(img)
img = cv2.merge((r,g,b))
im = Image.fromarray(img)
self.image = ImageTk.PhotoImage(image=im)
def resetCanvas(self):
self.canvas.create_image(0, 0, image=self.image)
self.canvas.place(x = 0, y = 0, height = self.image.height(), width = self.image.width())
Here is a screenshot showing a photo and how it is presented in the Tkinter canvas:
Here's what I have tried so far:
self.canvas = Tkinter.Canvas(self, width = self.image.width()*2, height = self.image.height()*2)
This does make the canvas larger (I can tell because I have some drawing functions on the canvas), but the image stays the same small size, not showing the entire imagecv2.imshow()
I see the full image, so it's not cv2
that is cutting off portions of the image. I realized what I have above is not a complete working example. I've pared the script down, and now running this I still see the same problem:
import Tkinter
import Image, ImageTk
from Tkinter import Tk, BOTH
from ttk import Frame, Button, Style
import cv2
import os
import time
import itertools
IMAGE_RESIZE_FACTOR = .3
class AppWindow(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.loadImage()
self.initUI()
def loadImage(self):
img = cv2.imread("w_4131.jpg")
img = cv2.resize(img, (0,0), fx = IMAGE_RESIZE_FACTOR, fy = IMAGE_RESIZE_FACTOR)
b, g, r = cv2.split(img)
img = cv2.merge((r,g,b))
im = Image.fromarray(img)
self.image = ImageTk.PhotoImage(image=im)
def initUI(self):
self.style = Style()
self.style.theme_use("default")
self.pack(fill=BOTH, expand=1)
print "width and height of image should be ", self.image.width(), self.image.height()
self.canvas = Tkinter.Canvas(self, width = self.image.width(), height = self.image.height())
self.canvas.pack()
self.canvas.create_image(0, 0, image=self.image)
def main():
root = Tk()
root.geometry("250x150+300+300")
app = AppWindow(root)
root.mainloop()
if __name__ == '__main__':
main()
The gist of it is that the image is passed by reference. If the reference is to a local variable, the memory referenced gets reused and the reference becomes stale. The variable storing the image should be in the same scope (has to have the same lifetime) as the Tk gui object it appears on.
When you place an image on a canvas at 0,0, that specifies the location of the center of the image, not the upper-left corner. The image is all there, it's just that you're only seeing the bottom-right corner.
Add anchor="nw"
when creating the image for the coordinates to represent the upper-left corner of the image:
self.canvas.create_image(0, 0, image=self.image, anchor="nw")
As for the canvas not being the same size of the image, I'm not seeing that. The image seems to fit the canvas perfectly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With