Ecore_Evas_Buffer_Example_01_c(3)

NAME
Ecore_Evas_Buffer_Example_01_c - Ecore_Evas buffer example Between the Evas examples, there is one in which one creates a canvas bound to the Evas buffer engine and uses its pixel contents to create an PPM image on disk.

There, one does that by creating the canvas 'by hand', with evas_new(), evas_engine_info_set(), etc.

On this example, we accomplish the very same task, but by using the Ecore_Evas helper wrapper functions on a buffer engine canvas. If you compare both codes, you'll see how much code one is saved from by using the Ecore_Evas wrapper functions.

The code is simple as it can be. After instantianting our canvas window, with ecore_evas_buffer_new(), we grab its canvas pointer and create the desired objects scene on it, which in this case is formed by 3 rectangles over the top left corner of a white background:

main(void)
{
   Evas *canvas;
   Evas_Object *bg, *r1, *r2, *r3;
   ecore_evas_init();
   ee = ecore_evas_buffer_new(WIDTH, HEIGHT);
   if (!ee) goto error;
   canvas = ecore_evas_get(ee);
   bg = evas_object_rectangle_add(canvas);
   evas_object_color_set(bg, 255, 255, 255, 255); /* white bg */
   evas_object_move(bg, 0, 0); /* at origin */
   evas_object_resize(bg, WIDTH, HEIGHT); /* covers full canvas */
   evas_object_show(bg);
   r1 = evas_object_rectangle_add(canvas);
   evas_object_color_set(r1, 255, 0, 0, 255); /* 100% opaque red */
   evas_object_move(r1, 10, 10);
   evas_object_resize(r1, 100, 100);
   evas_object_show(r1);
   r2 = evas_object_rectangle_add(canvas);
   evas_object_color_set(r2, 0, 128, 0, 128); /* 50% opaque green */
   evas_object_move(r2, 10, 10);
   evas_object_resize(r2, 50, 50);
   evas_object_show(r2);
   r3 = evas_object_rectangle_add(canvas);
   evas_object_color_set(r3, 0, 128, 0, 255); /* 100% opaque dark green */
   evas_object_move(r3, 60, 60);
   evas_object_resize(r3, 50, 50);
   evas_object_show(r3);

 Since it's a buffer canvas and we're using it to only save its contents on a file, we even needn't ecore_evas_show() it. We make it render itself, forcefully, without the aid of Ecore's main loop, with ecore_evas_manual_render():

   ecore_evas_manual_render(ee);

 And we're ready to save the window's shiny rendered contents as a simple PPM image. We do so by grabbing the pixels of the Ecore_Evas' internal canvas, with ecore_evas_buffer_pixels_get():

_scene_save(Evas *canvas,
            const char *dest)
{
   const unsigned int *pixels, *pixels_end;
   int width, height;
   FILE *f;
   evas_output_size_get(canvas, &width, &height);
   f = fopen(dest, "wb+");
   if (!f)
     {
        fprintf(stderr, "ERROR: could not open for writing '%s': %s,
                dest, strerror(errno));
        return;
     }

/* support function to save scene as PPM image */
static void
_scene_save(Evas *canvas,
            const char *dest)
{
   const unsigned int *pixels, *pixels_end;
   int width, height;
   FILE *f;
   evas_output_size_get(canvas, &width, &height);
   f = fopen(dest, "wb+");
   if (!f)
     {
        fprintf(stderr, "ERROR: could not open for writing '%s': %s,
                dest, strerror(errno));
        return;
     }
   pixels = ecore_evas_buffer_pixels_get(ee);
   pixels_end = pixels + (width * height);
   /* PPM P6 format is dead simple to write: */
   fprintf(f, "P6d %d55, width, height);
   for (; pixels < pixels_end; pixels++)
     {
        int r, g, b;
        r = ((*pixels) & 0xff0000) >> 16;
        g = ((*pixels) & 0x00ff00) >> 8;
        b = (*pixels) & 0x0000ff;
        fprintf(f, "%c%c%c", r, g, b);
     }
   fclose(f);
   printf("Saved scene as '%s', dest);
}

 Check that destination file for the result. The full example follows.

#ifdef HAVE_CONFIG_H
#include "config.h"
#else
#define EINA_UNUSED
#endif
#include <Ecore_Evas.h>
#include <stdio.h>
#define WIDTH  (320)
#define HEIGHT (240)
static Ecore_Evas *ee;
/* support function to save scene as PPM image */
static void
_scene_save(Evas *canvas,
            const char *dest)
{
   const unsigned int *pixels, *pixels_end;
   int width, height;
   FILE *f;
   evas_output_size_get(canvas, &width, &height);
   f = fopen(dest, "wb+");
   if (!f)
     {
        fprintf(stderr, "ERROR: could not open for writing '%s': %s,
                dest, strerror(errno));
        return;
     }
   pixels = ecore_evas_buffer_pixels_get(ee);
   pixels_end = pixels + (width * height);
   /* PPM P6 format is dead simple to write: */
   fprintf(f, "P6d %d55, width, height);
   for (; pixels < pixels_end; pixels++)
     {
        int r, g, b;
        r = ((*pixels) & 0xff0000) >> 16;
        g = ((*pixels) & 0x00ff00) >> 8;
        b = (*pixels) & 0x0000ff;
        fprintf(f, "%c%c%c", r, g, b);
     }
   fclose(f);
   printf("Saved scene as '%s', dest);
}
int
main(void)
{
   Evas *canvas;
   Evas_Object *bg, *r1, *r2, *r3;
   ecore_evas_init();
   ee = ecore_evas_buffer_new(WIDTH, HEIGHT);
   if (!ee) goto error;
   canvas = ecore_evas_get(ee);
   bg = evas_object_rectangle_add(canvas);
   evas_object_color_set(bg, 255, 255, 255, 255); /* white bg */
   evas_object_move(bg, 0, 0); /* at origin */
   evas_object_resize(bg, WIDTH, HEIGHT); /* covers full canvas */
   evas_object_show(bg);
   r1 = evas_object_rectangle_add(canvas);
   evas_object_color_set(r1, 255, 0, 0, 255); /* 100% opaque red */
   evas_object_move(r1, 10, 10);
   evas_object_resize(r1, 100, 100);
   evas_object_show(r1);
   r2 = evas_object_rectangle_add(canvas);
   evas_object_color_set(r2, 0, 128, 0, 128); /* 50% opaque green */
   evas_object_move(r2, 10, 10);
   evas_object_resize(r2, 50, 50);
   evas_object_show(r2);
   r3 = evas_object_rectangle_add(canvas);
   evas_object_color_set(r3, 0, 128, 0, 255); /* 100% opaque dark green */
   evas_object_move(r3, 60, 60);
   evas_object_resize(r3, 50, 50);
   evas_object_show(r3);
   ecore_evas_manual_render(ee);
   _scene_save(canvas, "/tmp/evas-buffer-simple-render.ppm");
   ecore_evas_free(ee);
   ecore_evas_shutdown();
   return 0;
error:
   fprintf(stderr, "error: Requires at least one Evas engine built"
                   " and linked to ecore-evas for this example to run"
                   " properly.);
   ecore_evas_shutdown();
   return -1;
}