[cairo] How to output images from data originating from files?
Ken Resander
kresander at yahoo.com
Fri Apr 5 13:40:01 PDT 2013
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 <simon.sapin at exyr.org>
To: cairo at cairographics.org
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
cairo at cairographics.org
http://lists.cairographics.org/mailman/listinfo/cairo
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cairographics.org/archives/cairo/attachments/20130405/8f1fde08/attachment.html>
More information about the cairo
mailing list