我试图了解从XGetImage
获取的数据是如何处理在内存中的:
XImage img = XGetImage(display, root, 0, 0, width, height, AllPlanes, ZPixmap);
现在假设我要分解红色,蓝色和绿色通道中的每个像素值。我怎么能以便携方式做到这一点?以下是一个示例,但它取决于XServer的特定配置,并不适用于所有情况:
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++) {
unsigned long pixel = XGetPixel(img, x, y);
unsigned char blue = pixel & blue_mask;
unsigned char green = (pixel & green_mask) >> 8;
unsigned char red = (pixel & red_mask) >> 16;
//...
}
在上面的例子中,我假设RGB
中pixel
个频道的特定顺序,并且像素的深度为24位:事实上,我有img->depth=24
和{{1 (屏幕也是24位深度)。但这不是一般情况。
作为第二步,我想摆脱XGetPixel并直接使用或描述img-&gt;数据。我需要知道的第一件事是img->bits_per_pixels=32
中是否有任何内容可以准确地提供我需要的所有信息来解释从Xlib
字段开始构建图像的方式,它们是:
答案 0 :(得分:2)
移位是掩码的一个简单功能:
int get_shift (int mask) {
shift = 0;
while (mask) {
if (mask & 1) break;
shift++;
mask >>=1;
}
return shift;
}
每个通道中的位数只是其掩码中的1位数(计算它们)。通道顺序由移位决定(如果红移为0,第一个通道为R等)。
我认为bits_per_pixel的有效值是1,2,4,8,15,16,24和32(15和16位是每像素格式相同的2字节,但前者有1位未使用)。我认为除了24和32 bpp之外,任何人都不值得支持。
X11不关心媒体文件,因此没有4CC代码。
答案 1 :(得分:0)
这可以从XImage
结构本身中读取。
- 每个像素中R,G,B通道的顺序;
这包含在XImage
结构的此字段中:
int byte_order; /* data byte order, LSBFirst, MSBFirst */
它告诉您是RGB还是BGR(因为它仅取决于机器的字节序)。
- 每个像素的位数;
可从此字段获取:
int bits_per_pixel; /* bits per pixel (ZPixmap) */
基本上是每个通道掩码中设置的位数:
unsigned long red_mask; /* bits in z arrangement */
unsigned long green_mask;
unsigned long blue_mask;
- 每个通道的比特位数;
请参见上文,或者您可以使用the code from @n.m.'s answer自己计算位数。
是的,如果他们也将位移常数也放入该结构中,那将是很好的选择,但显然他们决定不这样做,因为无论如何像素都是按“标准顺序”(RGB)对齐到字节的。当Xlib从X服务器检索数据时,即使它们内部存储在服务器端的不同格式中,Xlib也会确保将其转换为该顺序。因此,它始终是RGB格式,按字节对齐,但是根据机器的字节顺序,unsigned long
中的字节可以以相反的顺序出现,因此byte_order
字段可以告诉您有关的信息。
因此,要提取这些通道,只需在用0
,8
和{{1遮罩后,使用16
,red_mask
和green_mask
移位}},只需确保根据blue_mask
移入正确的字节,即可正常工作。