Updated 2012-09-10 14:36:21 by LkpPo

Graphic Interchange format, a compact and popular way of storing images. LZW-encoded. Tk's photo type of image allows both reading and writing GIF files. See http://www.datacompression.info/GIF.shtml for a series of references relating to GIF.

The GIF format may now be freely used as the primary LZW patent (4,558,302) has expired. See [http://en.wikipedia.org/wiki/GIF]

Salvatore Sanfilippo 14Oct2004: you can find BSD-licensed code for pure-Tcl GIF LZW encoding at [1].

How to make a single-pixel GIF file edit

 % set im [image create photo -height 1 -width 1]
 image4
 % $im put red
 % $im write im.gif -format gif
 % hexdump im.gif
 47 49 46 38 37 61 01 00 01 00 91 00 00 FF 00 00 # 0000 GIF87a..........
 FF FF FF FF FF FF FF FF FF 2C 00 00 00 00 01 00 # 0010 .........,......
 01 00 00 02 02 44 01 00 3B                      # 0020 .....D..;

Loading that file indeed shows a single red pixel. (A "hexdump" command is described at Dump a file in hex and ASCII.)

See also ".gif color dot" for a pure-Tcl version.

Writing a larger GIF file edit

    image create photo fooble -width 100 -height 100
    fooble blank
    for { set x 0 } { $x < 100 } { incr x } {
        for { set y 0 } { $y < 100 } { incr y } {
            if { $x >= 38 && $x <= 62 && $y >= 12 && $y <= 87
                 || $x >= 12 && $x <= 87 && $y >= 38 && $y <= 62 } {
                fooble put \#ffffff -to $x $y
            } else {
                fooble put \#ff0000 -to $x $y
            }
        }
    }
    grid [label .test -image fooble]
    fooble write swissflag.gif -format gif

Reading GIF image dimensions edit

AMG: This proc returns a two-element list consisting of the width and height, in that order, of the named image file. If the image isn't a valid GIF, it raises an error. It only needs to look at the first ten bytes of the file to get the data it needs. It probably won't work right for images with width or height greater than 32,767 pixels. ;^)
proc get_gif_dimensions {filename} {
  set img [open $filename rb]
  set data [read $img 10]
  close $img
  if {[binary scan $data a6s2 header size] != 2 || $header ni {GIF87a GIF89a}} {
    error "invalid GIF"
  } else {
    return $size
  }
}

See Reading GIF image dimensions for another implementation that's compatible with older versions of Tcl.

See also edit