A Simple Image Viewer

Fredrik Lundh | May 2003 | Originally posted to online.effbot.org

Here’s a simple image viewer widget, designed for use with the Tkinter version of the Widget Construction Kit.

from PIL import ImageTk
from WCK import Widget

class ImageView(Widget):

    ui_option_width = 512
    ui_option_height = 512

    def __init__(self, master, **options):
        self.photo = self.image = None
        self.ui_init(master, options)

    def ui_handle_config(self):
        return (
            int(self.ui_option_width),
            int(self.ui_option_height)
        )

    def ui_handle_repair(self, draw, x0, y0, x1, y1):
        if self.photo is None:
            return
        if self.image is None:
            self.image = self.ui_image(str(self.photo))
        draw.paste(self.image)

    def setimage(self, image):
        self.photo = ImageTk.PhotoImage(image)
        self.image = None
        self.ui_damage()

This widget uses the ui_image method to wraps an image object in a WCK-specific pixmap object. The pixmap is then pasted onto the window surface in the ui_handle_repair method.

The image object must be of a type known to the actual WCK implementation. For the Tkinter version of the WCK, the ui_image method currently requires a Tkinter PhotoImage instance, or the corresponding PIL object.

Note that the viewer creates the WCK object when the widget is about to be redrawn (in ui_handle_repair. The reason for this is that the ui_image method requires the widget to exist; if you try to call it on a widget that hasn’t yet been displayed, the method may fail. (in the current release, doing this may even crash the WCK library).

Using this widget is straightforward. Just create the widget as usual (by calling the widget constructor, passing in the parent widget), and call setimage with a PIL Image object. If necessary, you can also call the config method to resize the widget.

Here’s an example:

from Tkinter import Tk
from PIL import Image

root = Tk()
root.title("viewer")

view = ImageView(root)
view.pack()

image = Image.open(filename)

view.setimage(image)
view.config(width=image.size[0], height=image.size[1])

root.mainloop()

A drawback with the current ui_image interface is that the method requires a platform-specific image object. In future versions, the method will be modified to accept a standard PIL Image as well.

 

A Django site. rendered by a django application. hosted by webfaction.