如何创建尺寸与关联窗口不一致的XCB图像?
完全可以创建和窗口尺寸不同的XCB图像,你的代码问题出在两点:
1. 图像格式选择错误,内存计算不符合要求
你使用的XCB_IMAGE_FORMAT_XY_PIXMAP是位面分离存储格式,和常用的逐像素连续存储逻辑完全不同:比如24位色深下,XY格式会把所有像素的R通道值集中存在第一个数据块,G通道存在第二个,B通道存在第三个,实际所需的内存远大于你按byte_depth * width * height计算的结果。只有当宽高和窗口一致时,你申请的内存恰好满足XY格式的最小要求,函数才会正常返回。
2. 未考虑扫描线对齐规则
X11要求图像每一行的像素数据默认按4字节对齐,直接按宽×高×单像素字节数计算内存,当宽度不是4的整数倍时,实际所需内存会大于计算值,也会触发函数返回NULL。
修复方案
最简单的改法是切换为绝大多数场景使用的XCB_IMAGE_FORMAT_Z_PIXMAP格式,同时让xcb_image_create_native自动分配内存,避免手动计算出错:
把你创建图像的代码替换为下面的逻辑即可:
// 不需要手动malloc内存,传NULL让函数自动计算所需大小并分配 xcb_image_t *image = xcb_image_create_native(c, width, height, XCB_IMAGE_FORMAT_Z_PIXMAP, // 替换为Z格式 screen->root_depth, NULL, 0, NULL);
如果你确实需要手动管理像素内存,要先按对齐规则计算实际所需大小:
int byte_depth = screen->root_depth/8; // 计算4字节对齐的行长度 int stride = (width * byte_depth + 3) & ~3; int bytes = stride * height; void *base = malloc(bytes);
内容的提问来源于stack exchange,提问作者0rbitaldonkey
相关产品推荐
相关产品推荐

