Sam Far
Sam Far

Reputation: 35

Display a sequence of images using gtk in Linux

I have written a simple code to display a raw image buffer in a window using gtk:

#include <gtk/gtk.h>

int main (int argc, char *argv[])
{
    const int Width = 1920, Height = 1080;
    char *buffer = (char*)malloc(3 * Width * Height);

    // Read a raw image data from the disk and put it in the buffer.
    // ....

    GtkWidget *window;
    GtkWidget* image;

    gtk_init (&argc, &argv);

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data (buffer, GDK_COLORSPACE_RGB,
        FALSE, 8, Width, Height, Width*3, NULL, NULL);

    gtk_window_set_title (GTK_WINDOW (window), "Image Viewer");

    g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);

    image = gtk_image_new_from_pixbuf (pixbuf);
    gtk_container_add(GTK_CONTAINER (window), image);

    gtk_widget_show_all (window);

    gtk_main ();

    free (buffer);
    return 0;
}

How can I change this code to display a sequence of N images like a movie (i.e. continuous playback, not by choosing images manually using an image dialog box)? The main display loop is controlled by gtk_main() which ends when the user closes the window. I think the loop to assign the images to the image gadget should be inside an event handler of the image gadget, but I do not know that event handler.

Upvotes: 1

Views: 3011

Answers (1)

liberforce
liberforce

Reputation: 11454

In fact, this is trivial ;).

You need to understand that once you call gtk_main, everything is ruled by the GLib "main loop", which is an event loop like in pretty much all GUI toolkits. GTK will then react to events it receives.

So you need a way to create those events. If for example you want to perform an action periodically (the action here being "display a new picture"), you'd just call g_timeout_add and pass it a callback to call every second for example. Use the user_data parameter to pass a pointer a structure where you'll easily find your GtkImage as well as the list of images you want to display). In the callback, you will just change the image displayed, most likely using gtk_image_set_from_pixbuf.

g_timeout_add_seconds does the same thing as g_timeout_add, but with less precision (second instead of millisecond), but it has the advantage of being more battery friendly (less CPU wakeups = more energy saved).

You may also want to trigger an action on a different way that a timer. For that you have g_idle_add which will call your callback when the program is idle (no event to process).

Read the documentation of these functions in the documentation of the GLib main event loop.

Upvotes: 2

Related Questions