Version 12 of Tk image Dos and Don'ts

Updated 2003-07-05 18:33:25

Richard Suchenwirth -- Tk images (bitmap, photo, and whatever the future may bring) are handy and indispensable for fancy displays. This page shows how to enjoy them with even fewer problems (as pop up every now and then in news:comp.lang.tcl ).

DO DELETE UNWANTED IMAGES: It is easy to create an image, but in more complex applications large numbers of images may hang around cramming the memory (so-called "leaks" in Tcl would mostly come from such images). So, make it a rule to delete those images that you no longer need them. Also, images are memory objects. You can display the same image at various places of your GUI. No need to create it more than once, especially not in a loop.

DON'T FILL photo IMAGES PIXEL BY PIXEL! It looks intuitive, but is extremely slow to write

 for {set x 0} {$x<$xmax} {incr x} {
    for {set y 0} {$y<$ymax} {incr y} {
        $photo put $color -to $x $y
    }
 }

Rather, build up the data as a list of rows, each being a list of colors, and feed them to $photo put in one go:

 set data {{red yellow green blue} {white black orange purple} ...}
 $photo put $data -to 0 0

DON'T GIVE AN IMAGE NAME -- TAKE ONE! You may give an image a name at creation time, but maybe you shouldn't -- because a command with that name is created and might silently overwrite the original command or proc, be that "open", "close", or "menu" (DKF: you get a particularly interesting crash if you name the image "." as this completely blows Tk away within the current interpreter or crashes the whole app, depending on the version you are using) If you don't give an image name, image will give you a constructed name which will very probably not interfere with a proc. Example: don't say

    image create photo menu -arg ...

but say

    set img(menu) [image create photo -arg ...]

and use $img(menu) (which will look like image47) ever after.

DKF: I have edited the above to use an array; I find that more visually pleasing and less likely to interfere with anything else that is lying around...

DON'T USE THE -data OPTION! Jan Nijtmans wrote in the comp.lang.tcl newsgroup: Even faster should be not to use the "-data" option, but the "<imageName> put" command. This is almost equivalent, but it prevents the storage of a copy of the binary data in memory. Just replace the line:

     image create photo $pic -data $data

by the two lines:

     image create photo $pic
     $pic put $data

ulis, 2003-07-05: -data and put are NOT almost equivalent.

  • -data is cooked and receives a structured image (as a gif image)
  • put is raw and receives lines of pixels

See the header note at Serializing a photo.

Ro notes:

If you use the line:

     image create photo $pic -data $data

then it will throw an error if you are reading from a file of length zero. But if you use the two lines:

     image create photo $pic
     $pic put $data

then it will not throw an error if you are reading from a file of length zero. But it will prevent the storage of a copy of the binary data in memory, as noted above by Jan Nijtmans.

The moral of the story is: If you use the two latter lines, don't forget to check if the file is empty first, because otherwise, it will resize your picture to no size and not throw an error. This can be annoying if your picture is displaying in its own window and then all of a sudden you have a very small window to manipulate and you have to depend on your window manager to resize the window or close it.

This was tested on a gnu linux system with X11R6 4.0.1a


See also Images with transparency and plain images


Category Graphics | Don't do that | Arts and crafts of Tcl-Tk programming