Setting a ClutterImage using a GdkPixbuf

296 Views Asked by At

I'm trying to do what I would have thought would be trivial, but no matter what I try with a ClutterImage I get the error message Unable to load image data. The language I'm using is Vala, so there's a possibility that the Vapi file for Clutter is wrong. The GdkPixbuf that I have seems fine to me, I can set a GtkImage with it, and I can save it to disk without error, but if I read back the image file into the GdkPixbuf -> ClutterImage I get the same error from Clutter. I've also tried every value of COGL_PIXEL_FORMAT_* and it's always the same, I am positive though that the image data is in an RGB24 format.

My code is:

private Clutter.Content image;

construct {
    ...
    image = new Clutter.Image ();
    ...
}

public void set_image (Gdk.Pixbuf pixbuf) {
    lock (image) {
        unowned uint8[] pixels = pixbuf.get_pixels_with_length ();
        assert (pixels.length == pixbuf.width * pixbuf.height * 3);
        try {
            image.set_data (pixels,
                            Cogl.PixelFormat.RGB_888;
                            pixbuf.width,
                            pixbuf.height,
                            pixbuf.rowstride);
        } catch (Error e) {
            critical (e.message);
        }
    }
}

which I've adapted from what's in a C example in the documentation that can be seen at https://valadoc.org/clutter-1.0/Clutter.Image.set_data.html.

If it's at all relevant I can include the C code that Vala spits out, but it looks correct to me.

I was starting to think that the ClutterImage doesn't work, so I tried the example from https://github.com/GNOME/clutter/blob/master/examples/image-content.c with my image file that I saved using pixbuf.save (...) and it works. So now I'm thinking that it may be that I'm trying to use the image object as a ClutterActor in a GtkClutterEmbed widget. There's really not much to see there, the code is

var embed = new GtkClutter.Embed ();
viewport.add (embed);
var stage = embed.get_stage ();
image = new Clutter.Image ();
stage.content = image;

which to me looks the same as what's in the example that works, in that the stage is a ClutterActor and the ClutterImage is set as the actor content. So... I'm at a bit of a loss now.

Simple example

public static int main (string[] args) {
    GtkClutter.init (ref args);

    var window = new Gtk.Window ();
    var scrolled = new Gtk.ScrolledWindow (null, null);
    var embed = new GtkClutter.Embed ();

    window.add (scrolled);
    scrolled.add_with_viewport (embed);

    var pixbuf = new Gdk.Pixbuf.from_file ("image.png");
    var image = new Clutter.Image ();
    image.set_data (pixbuf.get_pixels (),
                    Cogl.PixelFormat.RGB_888,
                    pixbuf.width,
                    pixbuf.height,
                    pixbuf.rowstride);
    var stage = embed.get_stage ();
    stage.content = image;

    window.destroy.connect (Gtk.main_quit);
    window.show_all ();
    Gtk.main ();

    return 0;
}

Compiled using

valac --pkg cogl-1.0 --pkg clutter-gtk-1.0 --pkg gtk+-3.0 clutter-image-content.vala
1

There are 1 best solutions below

0
geoffjay On

I don't think this is related to Clutter any more, I think the issue was related to my video driver not being loaded properly and not having graphics acceleration. I finally got around to rebooting and had to rebuild the Nvidia modules, now I'm not getting the Unable to load data error. I'm getting a new one from the Aravis library, but that's completely unrelated to this. Not sure if I should just delete this question or not.