Cairo charge l’image à partir des données

J’ai un doute avec la bibliothèque du Caire.

J’ai téléchargé une image et je l’ai mise dans une mémoire tampon. Y at-il une solution au Caire pour charger une image à partir de données en mémoire?

Merci

Peut-être que vous voulez quelque chose comme gdk_pixbuf_new_from_data

http://developer.gnome.org/gdk-pixbuf/stable/gdk-pixbuf-Image-Data-in-Memory.html#gdk-pixbuf-new-from-data

Jetez un oeil à cairo_image_surface_create_for_data .

Vous pouvez charger des données d’image à partir de la mémoire, mais vous devez disposer cette mémoire dans le format correct attendu par Cairo.

Pour ce que vous décrivez, il est probablement plus facile de sauvegarder les données dans un fichier tmp et de laisser Cairo les charger à l’aide des opérations FILE. Cairo reconnaît plus de formats comme types de fichiers que comme structures en mémoire.

Lorsque j’ai utilisé cairo_image_surface_create_for_data pour les bitmaps, je devais convertir mes données bitmap Big-endian orientées octets en lignes Little-endian orientées mot-32 bits.

Vous pouvez constater, à la lecture de nombreux commentaires, que mes efforts ont parfois été réduits à des méthodes de recherche et d’essai et d’erreur. Mais j’ai la sortie désirée avec ce code. Volez ce que vous pouvez.

Encore une chose: la documentation pour les formats en mémoire (A8, RGB24, ARGB32) se trouve dans les fichiers .header, pas dans le manuel de référence.

 enum { BIG, LITTLE } endian = LITTLE; inline unsigned char reverse(unsigned char b) { return (b&1 ? 0x80: 0) | (b&2 ? 0x40: 0) | (b&4 ? 0x20: 0) | (b&8 ? 0x10: 0) | (b&0x10 ? 8: 0) | (b&0x20 ? 4: 0) | (b&0x40 ? 2: 0) | (b&0x80 ? 1: 0); } inline unsigned long wreverse(unsigned long w) { return ( ( w &0xFF) << 24) | ( ((w>>8) &0xFF) << 16) | ( ((w>>16)&0xFF) << 8) | ( ((w>>24)&0xFF) ); } unsigned char abit[2] = { 0, 0xFF }; unsigned char aspeck[4] = { 0, 0x55, 0xAA, 0xFF }; unsigned char anibble[16] = { 0, 36, 72, 108, 144, 180, 216, 255 }; unsigned char *amap[] = { abit, aspeck, anibble }; void drawimage(state *st, int wid, int hgt, int bits, unsigned char *samp, unsigned char *tmap) { int ssortingde; //ssortingde = cairo_format_ssortingde_for_width(CAIRO_FORMAT_A8, wid); ssortingde = cairo_format_ssortingde_for_width(CAIRO_FORMAT_RGB24, wid); //ssortingde = cairo_format_ssortingde_for_width(CAIRO_FORMAT_ARGB32, wid); int n; //unsigned char data[n=ssortingde*hgt]; unsigned char data[n=ssortingde*hgt*4]; memset(data, 0, n); //unsigned char *data; data = calloc(n=ssortingde*hgt, 1); unsigned long *ldata = (void *)data; int spo = 8/bits; /* samples per octet */ int span = wid/spo + (wid%spo?1:0); /* byte width */ int i,j; for (i=0; i < hgt; i++) { for (j=0; j < wid; j++) { unsigned char t; /*if (bits==8) t = samp[i*span + j/spo]; else*/ t = ( ( samp[i*span + j/spo] >> (/*7 -*/ (j%spo)/* *bits */) ) & (0xFF >> (8-bits)) ) /*<< (8-bits)*/; if (bits < 8) t = amap[bits==1?0:bits==2?1:2][t]; t = tmap[t]; /* map value through the transfer map */ //printf("%2X ", t); //data[i*stride + j] = t; ldata[i*stride/4 + j] = /*0x80<<24 |*/ t<<16 | t<<8 | t; } //puts(""); } /* for (i=0; i < hgt; i++) { //for (j=0; j < stride; j++) //printf("%2X ", data[i*stride + j]); for (j=0; j < stride/4; j++) printf("%2lX ", ldata[i*stride/4 + j] & 0xFF); puts(""); } */ cairo_surface_t *surf; //surf = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_A8, wid, hgt, stride); surf = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_RGB24, wid, hgt, stride); //surf = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, wid, hgt, stride); //cairo_mask_surface(st->cr, surf, 0, 0); cairo_set_source_surface(st->cr, surf, 0, 0); cairo_paint(st->cr); cairo_surface_flush(st->surface); if (st->dis) XFlush(st->dis); cairo_surface_destroy(surf); //free(data); } OPFN_ void image(state *st, object w, object h, object bits, object mat, object proc) { unsigned char tmap[256]; switch (bits.ui) { case 1: case 2: case 4: case 8: break; default: error(st, rangecheck); } int n; int i; unsigned char data[n=wui*hui/(8/bits.ui)]; /* map gray scale through the transfer function */ for (i = 0; i < 256; i++) { object v; v = consreal((double)i/255); push(v); pushe(consoper(st, "quit", NULL,0,0)); pushe(consoper(st, "exec", NULL,0,0)); pushe(consoper(st, "currenttransfer", NULL,0,0)); run(st); v = pop(); if (v.tag==integertype) promote(v); if (v.tag!=realtype) error(st, typecheck); tmap[i] = vur * 255; } for (i = 0; i < n; ) { object s; pushe(consoper(st, "quit", NULL,0,0)); pushe(proc); run(st); if (tos-os < 1) error(st, stackunderflow); s = pop(); if (s.tag != stringtype) error(st, typecheck); memcpy(&data[i], STR(s), sucn); i += sucn; } if (DEBUG) { for (i=0; icr) { gsave(st); cairo_new_path(st->cr); cairo_rectangle(st->cr, 0, 0, 1, 1); cairo_clip(st->cr); { cairo_masortingx_t cm, icm; psm2cm(st, mat, &cm); cminvert(&cm, &icm); cairo_transform(st->cr, &icm); } cairo_set_source_rgb(st->cr, 0.0, 0.0, 0.0); drawimage(st, wui, hui, bits.ui, data, tmap); grestore(st); } }