cookbook: Add a recipe for image loading

http://bugzilla.clutter-project.org/show_bug.cgi?id=2165

Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
This commit is contained in:
Elliot Smith 2010-06-29 15:49:40 +01:00 committed by Emmanuele Bassi
parent f2361a65de
commit 347f3b614d

View File

@ -996,6 +996,214 @@ clutter_texture_get_base_size (CLUTTER_TEXTURE (texture), &width, &height);
</section>
<section id="textures-image-loading">
<title>Loading image data into a texture</title>
<section>
<title>Problem</title>
<para>You want to display an image inside a Clutter
application.</para>
</section>
<section>
<title>Solution</title>
<para>Create a ClutterTexture directly from an image file:</para>
<informalexample>
<programlisting>
<![CDATA[
ClutterActor *texture;
GError *error = NULL;
gchar *image_path = "/path/to/image";
texture = clutter_texture_new_from_file (image_path, &error);
if (error != NULL)
{
// handle error
}
]]>
</programlisting>
</informalexample>
<para>Or create a texture and set its source to an image
file:</para>
<informalexample>
<programlisting>
<![CDATA[
ClutterActor *texture;
GError *error = NULL;
gchar *image_path = "/path/to/image";
gboolean loaded;
texture = clutter_texture_new ();
/*
* returns FALSE if file could not be loaded or texture
* could not be set from image data in the file
*/
loaded = clutter_texture_set_from_file (CLUTTER_TEXTURE (texture),
image_path,
&error);
if (error != NULL)
{
// handle error
}
]]>
</programlisting>
</informalexample>
</section>
<section>
<title>Discussion</title>
<para>Bear the following in mind when loading images into a
texture:</para>
<itemizedlist>
<listitem>
<para>An image load may fail if:
<itemizedlist>
<listitem>
<para>The file does not exist.</para>
</listitem>
<listitem>
<para>The image format is unsupported: most of the
common bitmap formats (PNG, JPEG, BMP, GIF, TIFF, XPM)
are supported, but more exotic ones may not be.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>Whether you're creating a texture from an image file,
or loading an image from a file into an existing texture,
you should specify the filesystem path to the file, rather
than a URI.</para>
</listitem>
</itemizedlist>
<section>
<title>Synchronous vs. asynchronous image loading</title>
<para>The code examples above show the simplest approach:
loading an image into a texture synchronously. This means that
the application waits for each image to be loaded before continuing;
which is acceptable in this case, but may not be when
loading images into multiple textures.</para>
<para>Another approach is to load data into textures
asynchronously. This requires some extra set up in your code:</para>
<itemizedlist>
<listitem>
<para>Call g_thread_init() (from the GLib library) prior
to calling clutter_init(), so that a local thread is used
to load the file, rather than the main loop. (Note that
this is not necessary if you're using GLib version >= 2.24,
since GObject initializes threading with the type system.)</para>
</listitem>
<listitem>
<para>Set the texture to load data asynchronously.</para>
</listitem>
<listitem>
<para>Connect a callback to the texture's load-finished
signal to handle any errors which occur during loading,
and/or to do extra work if data loads successfully.</para>
</listitem>
</itemizedlist>
<para>The code below shows how to put these together:</para>
<informalexample>
<programlisting>
<![CDATA[
/* callback to invoke when a texture finishes loading image data */
static void
_load_finished_cb (ClutterTexture *texture,
gpointer error,
gpointer user_data)
{
GError *err = (GError *)error;
gchar *image_path = (gchar *)user_data;
if (err != NULL)
g_warning ("Could not load image from file %s; message: %s",
image_path,
err->message);
else
g_debug ("Image loaded from %s", image_path);
}
int
main (int argc, char *argv[])
{
/* initialize GLib's default threading implementation */
g_thread_init (NULL);
clutter_init (&argc, &argv);
/* ... get stage etc. */
ClutterActor *texture;
GError *error = NULL;
texture = clutter_texture_new ();
/* load data asynchronously */
clutter_texture_set_load_async (CLUTTER_TEXTURE (texture), TRUE);
/* connect a callback to the "load-finished" signal */
g_signal_connect (texture,
"load-finished",
G_CALLBACK (_load_finished_cb),
image_path);
/* load the image from a file */
clutter_texture_set_from_file (CLUTTER_TEXTURE (texture),
image_path,
&error);
/* ... clutter_main () etc. */
}
]]>
</programlisting>
</informalexample>
</section>
<section>
<title>Other ways to load image data into a texture</title>
<para>While it's useful to load image data into a texture directly
from a file, there are occasions where you may have image data
in some other (non-file) format:</para>
<itemizedlist>
<listitem>
<para>Various GNOME libraries provide image data in GdkPixbuf
structures; clutter-gtk has functions for
creating or setting a texture from a GdkPixbuf:
gtk_clutter_texture_new_from_pixbuf()
and gtk_clutter_texture_set_from_pixbuf() respectively.</para>
</listitem>
<listitem>
<para>If you have raw RGB or YUV pixel data, ClutterTexture has
clutter_texture_set_from_rgb_data() and
clutter_texture_set_from_yuv_data() methods for loading it.</para>
</listitem>
</itemizedlist>
</section>
</section>
</section>
</chapter> <!-- textures }}} -->
<!--