XPutImage() 没有正确显示图像

XPutImage() isnt displaying the image correctly

幸好我不是一个会放弃的人... 但是我浪费了整整一天,我什至没有达到接近

正如一条评论指出的那样,我有点忘了说 objective/problem 是什么,我想打开一个 X window,并使用 XPutImage 显示一个简单的 png 图像。 当我不使用 Pixmap 时,无论我如何格式化传入数据,它都会将看似随机的像素分散到各处。当我使用 Pixmap 时,无论我尝试了什么,window 仍然是黑色的... 一切都在编译时带有一些未使用的小变量警告(自推送到回购协议后我解决了)

image=readpng_verificar(args.decode_arg, &rowbytes, &pwidth, &pheight);
uint8_t *pont=MatrizParaVetor((uint8_t **)image.vetor, pheight, rowbytes);
pont=displaygrap_winrite(pont,pwidth, pheight, 8, rowbytes, args.decode_arg);

image 是我存储 3 个东西的地方,即 2 个与 pnglib 相关的指针(没有问题),最后一个指针是一个 unsigned char ** 为此,我们只需要关注双点 uint8 变量 所以我通过 image.vetor 传递那个变量,所以它从一个无符号字符 ** 转换为一个简单的无符号字符 * (将不同的高度连接成一个向量而不是矩阵) 这是 MatrizParaVetor()

中的代码
uint8_t * MatrizParaVetor(uint8_t** matriz, uint32_t hei, size_t rwb){
    uint8_t *vetor=NULL;
    vetor =calloc(hei*rwb,sizeof(uint8_t));
    FILE * ok; 
    ok = fopen("teste.txt", "w");
    for (uint32_t y = 0; y < hei; y++){
        //memcpy(vetor[y], matriz[y], 30);
        //vetor=memmove(&(vetor[y*rwb]), matriz[y], 10);
        for (size_t x = 0; x < rwb; x+=4){
            vetor[y*x]=matriz[y][x];
            vetor[y*x+1]=matriz[y][x+1];
            vetor[y*x+2]=matriz[y][x+2];
            vetor[y*x+3]=0;
            //fprintf(ok, "%d\t%d\t%d\n",vetor[y*x],vetor[y*x+1],vetor[y*x+2]);
        }
        
    }
    fclose(ok);
    return vetor;
}

有些行只是用于调试(包括文件 IO),是的,我正在以稳定而缓慢的方式进行调试(因为其他行已经失败)。我只是希望它现在能工作。 我尝试了 memcpy 函数,但无论要复制或移动的大小如何,它似乎都会中止(即使它是非常短的值)。

好的,现在将那个向量放在最后一个函数中,我花了几个小时试图让它工作

uint8_t *displaygrap_winrite(uint8_t *vetor, uint32_t wid, uint32_t hei, uint8_t bitdepth,size_t rwb, const char *title){
    XImage *img;
    gfx_open(&wid, &hei, (const char *)title); 
    img=gfxvetor_image(vetor, bitdepth, wid, hei, rwb);
    gfx_image(img, wid, hei);
    //gfx_flush();
    if(waitForKey((uint8_t)XK_Escape,&wid, &hei)==1){
        
    }
    gfx_close();
    return vetor;
}

这将转到我经过大量修改的 gfx 库,它只是一个非常基本的图形库,使用 X11 在屏幕上显示内容。

void gfx_image(XImage *image, uint32_t wid, uint32_t hei){

//  GC gc;
    //XGCValues values;
    //gc = XCreateGC(gfx_display, gfx_window, 0, &values);
    Pixmap bitmap;
    
    bitmap = XCreatePixmap(gfx_display,gfx_window, wid, hei, image->depth);
    //TODO FIX OFFSET FIX DEST MAYBE DO MULTITHREADED ACTIOn
    
    XInitImage(image);
    //int a= XDrawRectangle(gfx_display, gfx_window,gfx_gc,10,10,wid+10,hei+10);
    //image->byte_order = MSBFirst;
    //image->bitmap_bit_order = MSBFirst;
    XPutImage(gfx_display,bitmap,gfx_gc,image, 0,0,0,0,wid,hei);
    //XCopyArea(gfx_display, image, bitmap, gfx_gc, 0,0,wid, hei, 0, 0);
    XSetWindowBackgroundPixmap(gfx_display, gfx_window,bitmap);
    //int           /* bitmap_pad */,
    //XImage
}
XImage *gfxvetor_image(uint8_t *data, uint8_t bitdepth, uint32_t wid, uint32_t hei, size_t rwb){
    XImage *image;
    
    Visual *visual = DefaultVisual(gfx_display,0);
    int screen = DefaultScreen(gfx_display);
    int dplanes = DisplayPlanes(gfx_display, screen);
    //image=(XImage *)malloc(sizeof(XImage));
    //image = XGetImage(gfx_display,gfx_display,0,0,wid,hei,dplanes, ZPixmap);
    //printf("\n%d\n",dplanes);
    //image->f.create_image(gfx_display, visual, dplanes, ZPixmap, 0, (char *)data, wid, hei, (int)bitdepth, (int)rwb);
    image = XCreateImage(gfx_display, visual, dplanes, ZPixmap, 0, (char *)data, wid, hei, (int)bitdepth, (int)rwb);
    //image->byte_order=MSBFirst;

    //image->bytes_per_line=rwb;
    //image->bits_per_pixel=32;
    //XInitImage(image);

    return image;
}

我已经完成 objective 解码 png 图像并使用 Xlib 将其显示在屏幕上。虽然我用来显示它的方法是放一个点并为其着色非常慢,但这是我想做的 100000 件待办事项中的一件事,该项目的回购在 https://github.com/Imeguras/xertin 的全部范围内代码

我只想让图片出现在屏幕上,Xlib 手册帮不了我的忙 对不起,我听起来有点不稳定,我很累但是感谢您的任何反馈或帮助

我查看了您的代码,我认为以下是您遇到的问题。

您似乎正在尝试修复函数 MatrizParaVetor 中的字节顺序问题。最好让 PNG 库为您执行此操作,因此我建议将此函数简化为以下内容:

uint8_t * MatrizParaVetor(uint8_t** matriz, uint32_t hei, size_t rwb){
    uint8_t *vetor = calloc(hei*rwb,sizeof(uint8_t));
    uint8_t *pCurrent = vetor;
    for (uint32_t row = 0; row < hei; row++)
    {
        uint8_t *pRow = matriz[row];
        memcpy(pCurrent, pRow, rwb);
        pCurrent += rwb;
    }
    return vetor;
}

这只是将指向行的指针数组转换为连续的像素图。

如果图片格式正确,函数gfxvector_image可以简化为:

XImage *gfxvetor_image(uint8_t *data, uint8_t bitdepth, uint32_t wid, uint32_t hei, size_t rwb){
    XImage *image;
    Visual *visual = DefaultVisual(gfx_display,0);
    int screen = DefaultScreen(gfx_display);
    int dplanes = DisplayPlanes(gfx_display, screen);
    image = XCreateImage(gfx_display, visual, dplanes, ZPixmap, 0, (char *)data, wid, hei, (int)bitdepth, (int)rwb);
    return image;
}

同样gfx_image可以简化为:

void gfx_image(XImage *image, uint32_t wid, uint32_t hei){
    XPutImage(gfx_display,gfx_window,gfx_gc,image, 0,0,0,0,wid,hei);
}

如果您现在 运行 您的代码并且在 test.png 中看到红色图像,那么一切都很好。如果图像显示为蓝色,则需要修改 readpng_verificar 函数。搜索对 png_set_alpha_mode 的调用,然后添加:

png_set_bgr(png_ptr);

这会将解码从红-绿-蓝分量顺序切换到蓝-绿-红分量顺序。