I'm trying to create a kiosk mode for Raspberry Pi, but I also want to be able to display a countdown (near the bottom) to a specific time like 9:00am and show itself like 0:00 or 00:00 respectively. The countdown needs to be independent of when the images change.

What is the best way to do this? Is there a viewer that already has this type of option?

I'm currently using feh which works for displaying the images, but has no way of showing the countdown. It would also be really nice to have the countdown automatically start and stop at different times, but I can work on that after I find a way to get it to show.


1 Answer 1


How about taking it as a programming exercise? The Raspi is about education, after all. Though people seem to prefer python, I prefer Tcl. It's so simple.

TESTED. It works. Adjust the parameters as you like. The program takes a list of directories to search for image files on the command line. The "Img" package is not required if you stick to the built-in image formats of Tk.


## Load required packages.
package require Tk
package require Img

## Parameters.
set ::geometry 1920x1080+0+0
set ::steps 9
set ::font [font create -size 100]
set ::posx 0
set ::posy 0
set ::anchor nw

## Global variables.
regexp {^([[:digit:]]+)x([[:digit:]]+)\+} $::geometry match ::screenwidth ::screenheight
set ::currentimage {}
set ::currentimageindex 0
set ::files {}

## Get all images files in all given directories.
foreach dir $argv {
    lappend ::files {*}[glob -nocomplain [file join $dir *]]

## Start procedure.
proc start {} {
    ## Configure the viewer window.
    canvas .imagebox -width $::screenwidth -height $::screenheight
    .imagebox create image 0 0 -tags image -anchor nw
    .imagebox create text $::posx $::posy -tags counter -anchor $::anchor -font $::font 
    .imagebox raise counter
    pack .imagebox -fill both -expand yes
    wm geometry . $::geometry
    wm overrideredirect . true
    wm withdraw .
    wm deiconify .

    ## Load first image.

## Load next image.
proc nextimage {} {
    ## Delete current image.
    catch {image delete $::currentimage}

    ## Load next image.
    set fd [open [list |convert -resize ${::screenwidth}x${::screenheight} [lindex $::files $::currentimageindex] jpeg:-] r]
    fconfigure $fd -translation binary
    set ::currentimage [image create photo -data [read $fd]]
    close $fd

    incr ::currentimageindex
    if {$::currentimageindex>=[llength $::files]} {
        set ::currentimageindex 0
    .imagebox itemconfigure image -image $::currentimage

    ## Countdown.
    nexttimerstep $::steps

## Next countdown step
proc nexttimerstep {countdown} {
    ## Set countdown text.
    .imagebox itemconfigure counter -text $countdown

    ## Check countdown.
    if {$countdown>0} {
        ## Update counter after one second.
        after 1000 [list nexttimerstep [expr {$countdown-1}]]
    } else {
        ## Load next image.

## Start after Tk is initialized.
after 0 start

## Start Tk event loop.
  • Wow! Thats amazing, I've never even heard of TCL. I should have made myself more clear. I'm trying to countdown to a specific time. This code appears to only shows the very top left of the image... Also is there anyway to make this detect the screen size instead of declaring it? Thanks again!
    – Nathan O
    Sep 16, 2018 at 1:43
  • 1
    I'm sorry, I still don't get what kind of countdown you want.
    – Janka
    Sep 16, 2018 at 1:48
  • I want a countdown that counts down to a time like 9:00am and shows the minutes, the countdown isn't for how long the image needs to be up but for something else. I edited my main question to be more clear for others.
    – Nathan O
    Sep 16, 2018 at 1:53
  • To address your first problem, I've edited the source so it now uses ImageMagick to resize the image to the window size before loading it.
    – Janka
    Sep 16, 2018 at 2:14
  • One could try to autodetect the geometry but as I have a dual screen setup, I cannot really test it. It's not so simple to get the geometry of individual monitors. Parsing the output of xrandr seems to be most simple.
    – Janka
    Sep 16, 2018 at 2:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.