helloB
helloB

Reputation: 3582

Tkinter canvas doesn't show entire photo image

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:

screenshot

Here's what I have tried so far:


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()  

Upvotes: 7

Views: 16485

Answers (1)

Bryan Oakley
Bryan Oakley

Reputation: 386372

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.

Upvotes: 16

Related Questions