开罗从数据加载图像

问题描述:

我对开罗图书馆有怀疑。开罗从数据加载图像

我下载了一张图片,并将其放入缓冲存储器中。在开罗有没有解决方案可以从内存中的数据加载图像?

感谢

您可以从内存中加载图像数据,但需要按照开罗预期的正确格式布置该内存。

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

当我使用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.u.i) { 
    case 1: case 2: case 4: case 8: break; 
    default: error(st, rangecheck); 
    } 
    int n; 
    int i; 
    unsigned char data[n=w.u.i*h.u.i/(8/bits.u.i)]; 


    /* 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] = v.u.r * 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), s.u.c.n); 
     i += s.u.c.n; 
    } 
    if (DEBUG) { for (i=0; i<n; i++) { printf("%02x ", data[i]); } puts(""); } 


    if (st->cr) { 
     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, w.u.i, h.u.i, bits.u.i, data, tmap); 
     grestore(st); 
    } 
} 
+1

该死的!我只注意到我的'anibble [16]'应该有16个值,而不是8个! – 2013-05-03 20:47:55

+0

不能在c中使用超短变量。 i.i.f更多的可读性会延长nms。 +,条件&循环与morb readbl与{}。 – yeoman 2016-09-08 07:15:06