Skip to content Skip to sidebar Skip to footer

Cannot Resize List Of Images On Canvas

I have a rectangle and two images on my canvas. When I resize by dragging window corner down and right this happens: The blue rectangle resizes properly. The red and green images

Solution 1:

Thanks to Stovfl's comment I was able to use:

self.itemconfig(items[idx], image=image)

To change the size of the image. Unfortunately the way the scaling works in tkinter:

# rescale all objects with the "all" tagself.scale("all",0,0,wscale,hscale)

The image wasn't filling the borders completely and missing a pixel or two. So I had to generate my own scaling factor based on original canvas width and height:

# images use ratio of original width/height to new width/height
wiscale = float(event.width)/self.startw
hiscale = float(event.height)/self.starth

Finally to prevent garbage collector from removing the resized image I assigned it to a list:

resized[idx]=image  # stop garbage collector from removing image

TL;DR

Here is the entire Python scrip in case you would like to use it in your own project:

#!/usr/bin/env python# -*- coding: utf-8 -*-try:
    from Tkinter import *
except ImportError:
    from tkinter import *

from PIL import Image, ImageTk

root = Tk()

images = []     # to hold the newly created image
resized = []    # Resized images
fills = []      # associated list of fill attributes
items = []      # associated list of canvass item tags / ids# a subclass of Canvas for dealing with resizing of windowsclassResizingCanvas(Canvas):
    def__init__(self,parent,**kwargs):
        Canvas.__init__(self,parent,**kwargs)

        self.bind("<Configure>", self.on_resize)
        self.height = self.winfo_reqheight()
        self.width = self.winfo_reqwidth()
        self.startw = self.width
        self.starth = self.height

    defon_resize(self,event):
        # determine the ratio of previous width/height to new width/height
        wscale = float(event.width)/self.width
        hscale = float(event.height)/self.height
        # Save new values as old values
        self.width = event.width
        self.height = event.height
        # images use ratio of original width/height to new width/height
        wiscale = float(event.width)/self.startw
        hiscale = float(event.height)/self.starth

        # resize imagesfor idx, image inenumerate(images):
            fill=fills[idx]
            neww=int(image.width()*wiscale)
            newh=int(image.height()*hiscale)
            image = Image.new('RGBA', (neww, newh), fill)
            image = ImageTk.PhotoImage(image)
            self.itemconfig(items[idx], image=image)
            resized[idx]=image  # stop garbage collector from removing image# resize the canvas 
        self.config(width=self.width, height=self.height)
        # rescale all objects with the "all" tag
        self.scale("all",0,0,wscale,hscale)

defcreate_rectangle(x1, y1, x2, y2, **kwargs):
    if'alpha'in kwargs:
        alpha = int(kwargs.pop('alpha') * 255)
        fill = kwargs.pop('fill')
        fill = root.winfo_rgb(fill) + (alpha,)
        fills.append(fill)
        image = Image.new('RGBA', (x2-x1, y2-y1), fill)
        images.append(ImageTk.PhotoImage(image))
        item=mycanvas.create_image(x1, y1, image=images[-1], anchor='nw')
        items.append(item)
    mycanvas.create_rectangle(x1, y1, x2, y2, **kwargs)

root.title('alpha1.py')

myframe = Frame(root)
myframe.pack(fill=BOTH, expand=YES)
WinWid=1490; WinHgt=860
mycanvas = ResizingCanvas(myframe,width=WinWid, height=WinHgt, \
                          highlightthickness=0)
mycanvas.pack(fill=BOTH, expand=YES)

create_rectangle(100, 100, 600, 600, fill='blue')
create_rectangle(300, 300, 950, 700, fill='green', alpha=.5)
create_rectangle(200, 500, 850, 820, fill='#800000', alpha=.6)
mycanvas.addtag_all("all")
for image in images:
    resized.append(image)

root.mainloop()

Post a Comment for "Cannot Resize List Of Images On Canvas"