|AniGif:| '''animated GIF-Images'''|
|Where:| http://cardtable.go.to/tcltk/|
|Mirrored here:| http://cardtable.sourceforge.net/tcltk/|
|Description:| [Tk] [extension] allowing you to create, start, stop, restart and destroy animated [GIF]s. Supports single play [image]s as well as images without full image data on each frame. Use gifsicle to uncompress compressed/interlaced GIFs before subsequent processing.|
|| Currently at version 1.3.|
|Updated:| 03/2002|
|Contact:| mailto:scfiead_spammenot@hotmail.com|
----
Is "animated gif" somehow a [Windows]-specific notion? Modern [Mac OS X] opens
animated gif-s with Preview, and Preview does ''not'' appear to animate.
<
>
''[Lars H]: I don't think it's Windows-specific, but I recall seeing the animation feature descibed as a bit of an oddity. Try opening in a web browser instead; I see the test animation on this page fine in Safari. It's possible that Preview lets you view each frame of the gif as a still image instead.''
The [Tk] code which follows, of course, executes and displays quite nicely on all platforms.
Note that it does not read the delay time out of the gif — it appears that [Img] does not provide such metadata. Fortunately here on the wiki is [gifblock] which can be used.
[SeS] Aug. 17th, 2015
Looking into the https://en.wikipedia.org/wiki/GIF%|%format description of a .gif%|%, I can tell that I need to search for the first 21 F9 data pattern in the file. The next two bytes we can ignore, the 2 bytes following is the frame rate. Based on my assumption, that this is the correct way to extract the frame rate, here the tcl solution:
======
proc getGifFrameRate {file} {
set d 0
set i 0
set f [open $file r]
fconfigure $f -translation binary
while {$i<1000} {
binary scan [read $f 2] s B1
if {$B1=="-1759"} {
binary scan [read $f 2] s B1
binary scan [read $f 2] s d
break
}
incr i
}
close $f
return $d
}
======
Not sayin this is the best way or fastest or whatever, just a quick and dirty method which works for me and the majority of .gif files I used to test it on. The returned value * 10ms is the frame rate in the file. Returns 0 if .gif is not an animated one.
----
[RS] 2004-07-27: Also, in plain [Tk] (but documented only for [Img]),
you have access to the partial images of an animated [GIF].
This code was enough for me:
======
package require Img
proc anigif file {
#-- returns a list of images from the given GIF file
set index 0
set results {}
while 1 {
if [catch {
image create photo -file $file -format "gif -index $index"
} res] {
return $results
}
lappend results $res
incr index
}
}
#-- Testing (dumping the animation phases, one next to the other, into a text widget):
======
[WikiDbImage anigif.jpg] Test image: [WikiDbImage underconstruction.gif]
======
#-- Testing (dumping the animation phases into a text widget, and an animation):
proc lcycle listName {
upvar 1 $listName list
set res [lindex $list 0]
set list [concat [lrange $list 1 end] [list $res]]
set res
}
proc every {ms body} {eval $body; after $ms [info level 0]}
set file [lindex $argv 0]
pack [text .t]
set images [anigif $file]
foreach img $images {
.t image create end -image $img
}
.t insert end animated:
set id [.t image create end -image [lindex $images 0]]
every 100 ".t image config $id -image \[lcycle ::images\]"
======
----
Here's a slightly more minimal-but-generalizable form, applied to a canvas:
======
proc animate_in_canvas {canvas gif} {
global id_list
# As written, there's only room for a single animation at a time.
set id_list {}
foreach img [anigif $gif] {
lappend id_list [.c create image 0 0 -anchor nw -image $img]
}
every 150 ".c raise \[lcycle ::id_list\]"
}
pack [canvas .c -height 300 -width 300]
animate_in_canvas .c [lindex $argv 0]
======
----
[mzgcoco]
======
#apply to a label
proc play {ms lbl img_list} {
set img [lindex [$lbl config -image] end]
set idx [lsearch $img_list $img]
incr idx
if {$idx > [llength $img_list] - 1} {
set idx 0
}
$lbl config -image [lindex $img_list $idx]
after $ms "play $ms $lbl \"$img_list\""
}
set img_list [anigif d:/dummy/ss.gif]
label .l -image [lindex $img_list 0]
pack .l
play 100 .l "$img_list"
======
----
[rahulj]
what about destroying animated gif canvas or label?
[SeS] Aug. 15th, 2015?
hey [rahulj], not 100% sure if I understood your question, but if it is what I think, then I propose the following mod in proc play:
======
if {[catch {set img [lindex [$lbl config -image] end]}]} {return}
======
This will effectively stop the play procedure in case the label is destoyed.
----
[SeS] Aug. 21, 2015
See also : [tG2 .gif animation wrapper]
----
<> Package | Animation | Graphics