1

カイロ図書館に疑問があります。

画像をダウンロードしてバッファメモリに入れました。メモリ内にあるデータから画像をロードするためのカイロの解決策はありますか?

ありがとう

4

3 に答える 3

4

イメージ データをメモリから読み込むことはできますが、Cairo が期待する正しい形式でそのメモリをレイアウトする必要があります。

あなたが説明したことについては、データを tmpfile に保存し、カイロに FILE 操作を使用してロードさせる方がおそらく簡単です。Cairo は、メモリ内構造よりも多くの形式をファイルタイプとして認識します。

ビットマップに使用cairo_image_surface_create_for_dataしたときは、バイト指向のビッグ エンディアン ビットマップ データを 32 ビット ワード指向のリトル エンディアンの行に変換する必要がありました。

散らばるコメントからわかるように、私の努力は時々、狩りとつつき、試行錯誤の方法に還元されました. しかし、このコードで目的の出力が得られました。あなたができるものをそれから盗みます。

もう 1 つ:インメモリ形式 (A8、RGB24、ARGB32) のドキュメントは.h、リファレンス マニュアルではなく、リーダー ファイルにあります。

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);
    }
}
于 2012-05-14T18:14:49.403 に答える
3

多分あなたは次のようなものが欲しいgdk_pixbuf_new_from_data

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

于 2011-03-10T09:51:01.970 に答える