Languages

Menu
Sites
Language
Issue on Cairo to create png image

Hi,

I am try to create a png image by using cairo, according the guide on help doc. 

Graphics Cairo Tutorial

    cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 240, 80);
	cairo_t *cairo = cairo_create (surface);
	cairo_rectangle(cairo, 10, 10, 220, 60);
	cairo_stroke(cairo);
	cairo_surface_write_to_png (surface, "cairo.png");
	cairo_surface_flush(surface);
	cairo_destroy (cairo);
	cairo_surface_destroy (surface);

Run the app on emulator, there isn't bug/error raised while app running. But actually I can't find the "cairo.png" image file on the emulator, by execute cammand on shell find / -name cairo.png

What's wrong in my sample code?

Responses

8 Replies
colin Rao
/* defines in .h file */
#include <cairo.h>
#define WIDTH 480
#define HEIGHT 800
#define NB_TEMPS 12

/* code in .c file */
typedef struct appdata {
    Evas_Object *win;
 Evas_Object *conform;
 cairo_t *cairo;
 cairo_surface_t *surface;
 Evas_Object *image;
 unsigned char *pixels;
} appdata_s;
static int temperatures[] = {
  -5, 0, 3, 9, 13, 18, 21, 29, 16, 10, 5, -2,
};

static void
create_base_gui(appdata_s *ad)
{
 int i;
    int max_temp;
    int min_temp;
    int x, y;
    double det, a, b;
    int row_stride;
 
 ad->win = elm_win_util_standard_add(PACKAGE, PACKAGE);
 elm_win_conformant_set(ad->win, EINA_TRUE);
 if (elm_win_wm_rotation_supported_get(ad->win))
 {
     int rots[4] = { 0, 90, 180, 270 };
     elm_win_wm_rotation_available_rotations_set(ad->win, (const int *)(&rots), 4);
 }
 evas_object_smart_callback_add(ad->win, "delete,request", win_delete_request_cb, NULL);

 ad->conform = elm_conformant_add(ad->win);
 evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
 elm_win_resize_object_add(ad->win, ad->conform);
 evas_object_resize(ad->win, 480, 800);
 evas_object_show(ad->win);
 evas_object_show(ad->conform);

 // Create an evas_object_image which contains the Cairo content
 ad->image = evas_object_image_add(evas_object_evas_get(ad->win));
 evas_object_image_alpha_set(ad->image, EINA_TRUE);
 evas_object_image_colorspace_set(ad->image, EVAS_COLORSPACE_ARGB8888);
 evas_object_image_size_set(ad->image, WIDTH, HEIGHT);
 evas_object_image_fill_set(ad->image, 0, 0, WIDTH, HEIGHT);
 evas_object_show(ad->image);

 row_stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, WIDTH);
 // Create the pixels
 ad->pixels = (unsigned char *) calloc(sizeof(unsigned char) * row_stride * HEIGHT, 1);
 // Create the cairo surface
 ad->surface = cairo_image_surface_create_for_data(ad->pixels, CAIRO_FORMAT_ARGB32, WIDTH, HEIGHT, row_stride);
    // Create the cairo context
 ad->cairo = cairo_create (ad->surface);
 // Set the pixels created as image's pixels
 evas_object_image_data_set(ad->image, ad->pixels);

 cairo_set_source_rgb(ad->cairo, 0.0, 0.0, 0.0);
 cairo_set_line_width(ad->cairo, 2);
 cairo_move_to(ad->cairo, 10, 10);
 cairo_line_to(ad->cairo, 10, HEIGHT);
 cairo_stroke(ad->cairo);

 max_temp = INT_MIN;
 min_temp = INT_MAX;
 for (i = 0; i < NB_TEMPS; i++)
 {
    max_temp = MAX(temperatures[i], max_temp);
    min_temp = MIN(temperatures[i], min_temp);
 }

 det = - (min_temp * 1 - max_temp * 1);
 a = (1 * 0 - 1 * HEIGHT) / det;
 b = (HEIGHT * max_temp - 0 * min_temp ) / det;

 // Select the red color to paint the grid
 cairo_set_source_rgba(ad->cairo, 1.0, 0.0, 0.0, 0.5);
 // Paint horizontal lines in red, with a thicker line for 0°C
 for (i = -10; i <= 40; i += 5)
 {
     // For the 0°C line, set a thicker pen
     if (i == 0)
         cairo_set_line_width(ad->cairo, 4);
     else
         cairo_set_line_width(ad->cairo, 1);
     // Calculate the y position
     y = (int)(a * i + b);
     cairo_move_to(ad->cairo, 10, y);
     cairo_line_to(ad->cairo, WIDTH, y);
     cairo_stroke(ad->cairo);
 }
 // Paint the 11 verticals lines (the first one is already painted as the black y axis)
 for (i = 1; i < 12; i++)
 {
     x = (int)(i * (WIDTH / NB_TEMPS) + 10);
     cairo_move_to(ad->cairo, x, HEIGHT);
     cairo_line_to(ad->cairo, x, 10);
 }
 cairo_stroke(ad->cairo);

 // Set a green value for temperature graph
 cairo_set_source_rgba(ad->cairo, 0.5, 0.8, 0.3, 0.8);
 cairo_set_line_width(ad->cairo, 10);
 // Iterate the array to get the temperature values of each month
 for (i = 0; i < NB_TEMPS; i++)
 {
     // x coordinate is easily calculated, because it is a multiple of the graph_size divided by the number of points
     x = (int)(i * (WIDTH / NB_TEMPS) + 10);
     // use the themp_to_pix function to set the y coordinate corresponding to the temp value
     y = (int)(a * temperatures[i] + b);

     cairo_line_to (ad->cairo, x, y);
 }
 cairo_stroke(ad->cairo);

 evas_object_image_data_update_add(ad->image, 0, 0, WIDTH, HEIGHT);
}

another example, in the same tutorials as previous comment. The actually output screen is blank, both on emulator and the real device. It's it possible, it's not supported on Win 7 64bit version. Just like the Native UI Builder template was only supported on Ubuntu. :)

Paste the source code here:

 

 

colin Rao

SDK version: 2.3 Rev2

Alex Ashirov

Hi,

What is value returned by cairo_surface_write_to_png()?

colin Rao

Hi, it's return a write error. 

    Details:CAIRO_STATUS_WRITE_ERROR
    Default:CAIRO_STATUS_WRITE_ERROR
    Decimal:11
    Hex:0xb
    Binary:1011
    Octal:013

Alex Ashirov

Hi,

It seems that you tried to write into wrong directory (permission denied). Could you please try to write into, for example, app_get_shared_trusted_path()?

colin Rao

Hi, Alex

Thanks! it's working correct now.

cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 240, 80);
cairo_t *cairo = cairo_create (surface);
cairo_rectangle(cairo, 10, 10, 220, 60);
cairo_stroke(cairo);
char filename[PATH_MAX];
snprintf(filename, sizeof(filename), "%s%s", app_get_shared_trusted_path(), "cairo.png");
dlog_print(DLOG_INFO, LOG_TAG, "%s\n", filename);
cairo_status_t r = cairo_surface_write_to_png (surface, filename);
dlog_print(DLOG_INFO, LOG_TAG, "%s\n", r);
cairo_surface_flush(surface);
cairo_destroy (cairo);
cairo_surface_destroy (surface);

 

Ibad Rehman

Hi ,

    I am trying the cairo graphics tutorial in which i m trying to show the temperature graph  using cairo. But the output is blank screen on both device and emulator.

   I am not even able  to draw the line or arc. Each time result is blank screen.

   Please help.

  

colin Rao

Same here, as the second comment of mine ( BY colin Rao, 6 Mar 2015, 00:47 ).

I still can't see the graph, it's blank. Maybe it's a low level bug in cairo, also possible we are in a wrong way.