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);
这会将解码从红-绿-蓝分量顺序切换到蓝-绿-红分量顺序。
幸好我不是一个会放弃的人... 但是我浪费了整整一天,我什至没有达到接近
正如一条评论指出的那样,我有点忘了说 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);
这会将解码从红-绿-蓝分量顺序切换到蓝-绿-红分量顺序。