【问题标题】:XPutImage() isnt displaying the image correctlyXPutImage() 没有正确显示图像
【发布时间】:2020-11-20 18:52:18
【问题描述】:

我不是要放弃的人... 但是我浪费了一整天,我还没有接近

正如一条评论指出的那样,我有点忘了说目标/问题是什么,我想打开一个 X 窗口,并用 XPutImage 显示一个简单的 png 图像。 当我不使用 Pixmap 时,无论我如何格式化传入数据,它都会将看似随机的像素散布到各处。当我确实使用 Pixmap 时,无论我尝试了什么,窗口都会保持黑色...... 一切都在编译,并带有一些小的未使用变量警告(自从推送到 repo 后我就解决了这个问题)

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);

图像是我存储 3 个东西的地方,即 2 个与 pnglib 相关的指针(无概率)和最后一个指针,它是一个无符号字符 ** 为此,我们只需要关注双指向的 uint8 变量 所以我通过 image.vetor 传递该变量,因此它从 unsigned char ** 转换为简单的 unsigned char * (将不同的高度连接成单个向量而不是矩阵) 这是 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;
}

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

我只想让图片出现在屏幕上,而 Xlib 手册并没有帮助我减轻疲劳 对不起,我听起来有点不稳定,我很累,但感谢任何反馈或帮助

【问题讨论】:

  • but it seemed to regardless of the size abort Ok now were使用 punctuation。句子以full stop 结尾。新句子以大写字母开头。我根本不明白你的描述 - 它只是一个斑点。请用英文重写。你为什么写在这里? 究竟您遇到的问题是什么?请看tour,请看How to Ask,我建议查看questions checklist
  • @KamilCuk 感谢您的快速回复,我已经使阅读线程变得更容易,如果我可以做任何事情来帮助你们理解问题,比如拍照或发布更多代码,请标记我,因为我很少在这里问问题,但似乎我已经没有关于这个话题的话题了,而且每一个话题都走上了不同的道路。

标签: c linux x11 xlib


【解决方案1】:

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

您似乎正在尝试修复函数 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);

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

【讨论】:

  • 我检查了您的答案,很快就会正确阅读您的回复
  • 谢谢,我应该检查一下我的方法出了什么问题,也许我只是复制了重复的代码,或者应该坚持使用 memcpy 方法而不是放弃我忘了添加这个 for (int row = 0; row
  • @Imeguras 很高兴这一切都为你解决了。感谢您指出警告。不知道我是怎么错过的。将更新答案。祝你的项目好运!
猜你喜欢
  • 2020-07-07
  • 1970-01-01
  • 2018-11-02
  • 2013-06-23
  • 1970-01-01
  • 2021-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多