开罗从数据加载图像

我对cairo库有疑问。

我下载了一张图片,然后将其放入缓冲存储器中。 在cairo中是否有任何解决方案从内存中的数据加载图像?

谢谢

也许你想要像gdk_pixbuf_new_from_data这样的gdk_pixbuf_new_from_data

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

看看cairo_image_surface_create_for_data 。

您可以从内存加载图像数据,但是您需要以Cairo期望的正确格式布置该内存。

对于您所描述的内容,将数据保存在tmpfile中并让Cairo使用FILE操作加载它可能更容易。 开罗认为更多格式为文件类型,而不是内存结构。

当我使用cairo_image_surface_create_for_data作为位图时,我不得不将面向字节的Big-endian位图数据转换为面向32位字的Little-endian行。

你可以从评论的乱扔垃圾中看出,有时我的努力被简化为狩猎和啄,试错法。 但是我用这段代码得到了所需的输出。 从中偷走你能做到的。

还有一件事:内存格式(A8,RGB24,ARGB32)的文档位于.h eader文件中,而不是参考手册中。

 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 stride; //stride = cairo_format_stride_for_width(CAIRO_FORMAT_A8, wid); stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, wid); //stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, wid); int n; //unsigned char data[n=stride*hgt]; unsigned char data[n=stride*hgt*4]; memset(data, 0, n); //unsigned char *data; data = calloc(n=stride*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_matrix_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); } }