Re: How to output images from data originating from files?

Ken Resander <[email protected]>
Newsgroups gmane.comp.lib.cairo
Message-ID <[email protected]>
Hi Simon,

Thanks for the very useful advice...

I can make the GdkPixbufLoader work if the program does not prepare eventhandlers for area-prepared and area-updated. However, if I connect these they will not trigger and call the handlers. 

The test program is small so I can add it inline.

Hope someone can see what is wrong...

Ken
P.S. The test program:
static cairo_surface_t * imgpng ;

static unsigned char bigbuf [ 200000 ] ;
static GdkPixbuf * pixbuf;
static GdkPixbufLoader * loader ;


static GdkPixbuf * makepixbuf ( bool byfilename , const char * filename )
   {
   GError * err = NULL ;
   if ( byfilename )
      {
      return gdk_pixbuf_new_from_file(filename,&err);
      }
   // read file content into buffer
   FILE * f = fopen ( filename, "r");
   int length = fread (bigbuf, 1, sizeof(bigbuf), f);
   fclose (f);
   loader = gdk_pixbuf_loader_new ();
   gdk_pixbuf_loader_write (loader, bigbuf, length, NULL);
   gdk_pixbuf_loader_close (loader , &err ) ;
   //printf ( "pixbuf may not yet be ready...\n" ) ;
   //return NULL ;
  // actually it is ready here!!!!!
  return pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
   }

static void do_drawing(cairo_t *cr)
   {
   cairo_set_source_surface(cr, imgpng , 0,40);
   cairo_paint(cr);

   if ( pixbuf != NULL )
      {
      gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 150);
      cairo_paint (cr);
      }
   }

static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr,
                              gpointer user_data)
   {
   cr = gdk_cairo_create(gtk_widget_get_window(widget));
   do_drawing(cr);
   cairo_destroy(cr);
   return FALSE;
   }

static void on_area_prep( GdkPixbufLoader *loader, gpointer user_data)
   {
   // this is not called
   printf ( "area-prepared: pixbuf ready\n" ) ;
   pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
   }


static void on_area_update( GdkPixbufLoader *loader, gint x , gint y , gint width ,
                          gint height , gpointer user_data)
   {
   // same here - not called
   printf ( "area-updated: pixbuf ready\n" ) ;
   pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
   }

int main(int argc, char *argv[])
   {
   GtkWidget *window;
   GtkWidget *darea;

   gtk_init(&argc, &argv);

   imgpng = cairo_image_surface_create_from_png("sample_7.png");
   pixbuf = makepixbuf ( false , "parrots.jpg" );

   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

   darea = gtk_drawing_area_new();
   gtk_container_add(GTK_CONTAINER(window), darea);

   g_signal_connect(G_OBJECT(darea), "draw",
                    G_CALLBACK(on_draw_event), NULL);
   g_signal_connect(G_OBJECT(loader), "area-prepared",
                    G_CALLBACK(on_area_prep), NULL);
   g_signal_connect(G_OBJECT(loader), "area-updated",
                    G_CALLBACK(on_area_update), NULL);
   g_signal_connect(window, "destroy",
                    G_CALLBACK(gtk_main_quit), NULL);

   gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
   gtk_window_set_default_size(GTK_WINDOW(window), 400, 90);
   gtk_window_set_title(GTK_WINDOW(window), "GTK window");

   gtk_widget_show_all(window);

   gtk_main();

   cairo_surface_destroy(imgpng);

   return 0;
   }




 


________________________________
 From: Simon Sapin <[email protected]>
To: [email protected] 
Sent: Friday, 5 April 2013, 15:13
Subject: Re: [cairo] How to output images from data originating from files?
 
Le 05/04/2013 16:03, Ken Resander a écrit :
> I am new to Cairo and have fairly limited knowlege of graphics (Windows
> GDI,GDI+ years ago).
> I am now on Ubuntu 12.04 and need to render images in png and jpg from
> GTK in C/C++.
>
> I know how to do this when specifying .png and .jpg file names:
>
> cairo_surface_t * imgpng =
> cairo_image_surface_create_from_png("sample_7.png");
> cairo_set_source_surface(cr, imgpng, 0,40);
> cairo_paint(cr);
>
> GError * err = NULL;
> GdkPixbuf * imgpxb = gdk_pixbuf_new_from_file("parrots.jpg",&err);
> gdk_cairo_set_source_pixbuf(cr, imgpxb, 0, 150);
> cairo_paint (cr);
>
> My program will receive image data from another computer via standard
> protocols. There might be hundreds of small to small-medium images
> coming, so it would more efficient to batch the file content of these
> into a huge buffer and pass that across (from the other computer) along
> with the image format, buffer offset and length of each chunk.
>
> Of course I could copy a chunk into a tmp file and use the png surface
> and gdkpixbuf filename api calls above, but it seems such a shame having
> to put the data back into a file for cairo/gdk to read and convert it to
> the format needed.
>
> Is there a better way?

Hi,

If you have images (not all PNG) in memory, the easiest way to load them 
without going through temporary files is to use GdkPixbufLoader:

https://developer.gnome.org/gdk-pixbuf/stable/GdkPixbufLoader.html

This will give you GdkPixbuf objects that you can convert to cairo 
patterns with gdk_cairo_set_source_pixbuf, as you do above.

Cheers,
-- 
Simon Sapin
-- 
cairo mailing list
[email protected]
http://lists.cairographics.org/mailman/listinfo/cairo

-- 
cairo mailing list
[email protected]
http://lists.cairographics.org/mailman/listinfo/cairo
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.