我正在尝试使用普通 xlib 显示图像,我几乎成功了,但由于某种原因,结果图像与颜色不同。这是如何显示图像的代码片段:
/* preceeding initialization */
image = XCreateImage(display, CopyFromParent, XDefaultDepth(display, screen), ZPixmap, 0, buffer, width, height, 32, 0);
XPutImage(display, window, XDefaultGC(display, screen), image, 0, 0, 0, 0, width, height);
/* handling events */
buffer
包含由另一个库检索的图像像素。原图如下:
由于某种原因,蓝色和红色被调换了,黄色不知何故变成了青色。我认为问题在于图片本身的颜色深度(8 位)和屏幕深度(24 位)不同。如果我理解正确,xlib 希望将每个像素视为 3 个字节(24 位),但图像每个像素仅包含 1 个字节(8 位)。我也尝试用
XGetVisualInfo
改变窗口的颜色深度,但返回结果中没有少于 24 位的选项。或者我误解了像素是如何存储在内存中的?是不是和字节数组一样,像这样:
11111111 R
11111111 G
11111111 B
11111111 R
00000000 G
11111111 B
00000000 R
11111111 G
11111111 B
等等……
我还尝试用另一个
lib显示相同的
buffer
像素,并且一切正常,所以问题出在我的代码中。我没有用Pixmap
bcs 没有区别,结果是一样的。
终于修好了。我所要做的就是通过调用
XPutPixel
手动放置每个像素,这里是片段:
let mut x = 0;
let mut y = 0;
let mut idx = 0;
loop {
XPutPixel(image, x, y, u32::from_be_bytes([buffer[idx + 3], buffer[idx], buffer[idx + 1], buffer[idx + 2]]) as u64);
if x < img_info.width - 1 {
x += 1;
} else {
x = 0;
y += 1;
}
if y == img_info.height - 1 {
break;
}
idx += 4;
}
/* further event handling, window mapping etc. */
我发现 X 服务器使用的是
ARGB
像素格式,而不是 RGBA
或 RGB
。第一个字节也可以是 0,我没有发现任何区别。但我仍然不明白是否每个 X 服务器都使用这种像素格式,还是只是我的情况?我在 Xlib 文档中找不到任何关于它的信息,也许如果我对此有任何运气,答案就会完成。