Open Frameworks中如何将RGB32格式图像转换为ofPixels对象
OF中RGB32字节数组转ofPixels实现方案
方案1:零拷贝直接绑定(性能最优)
如果你的解码库输出的字节数组生命周期可控,且像素无行对齐填充,可以直接用setFromExternalPixels方法绑定外部缓冲,无需内存拷贝:
// 提前获取视频分辨率参数 int vidWidth = 你的视频宽度; int vidHeight = 你的视频高度; unsigned char* decodeBuf = 解码库输出的RGB32字节数组指针; ofPixels pix; // 若像素排布为R-G-B-A顺序,使用OF_PIXELS_RGBA // 若排布为B-G-R-A顺序(和QT QImage::Format_RGB32内存排布一致),使用OF_PIXELS_BGRA pix.setFromExternalPixels(decodeBuf, vidWidth, vidHeight, OF_PIXELS_RGBA); // 直接加载到纹理即可绘制 ofTexture renderTex; renderTex.loadData(pix);
注意:该方案需保证
decodeBuf在pix和纹理使用期间不会被释放,否则会触发内存访问错误。
方案2:内存拷贝适配(兼容性最好)
如果无法保证外部缓冲生命周期,或者字节顺序/行对齐不符合要求,可以手动拷贝像素数据:
无行对齐,仅需调整字节顺序的场景:
int vidWidth = 你的视频宽度; int vidHeight = 你的视频高度; unsigned char* decodeBuf = 解码库输出的RGB32字节数组指针; ofPixels pix; pix.allocate(vidWidth, vidHeight, OF_PIXELS_RGBA); for (int i = 0; i < vidWidth * vidHeight; i++) { int bufPos = i * 4; // 以下适配QT Format_RGB32的BGRA内存排布,转成OF默认RGBA格式 pix[i*4 + 0] = decodeBuf[bufPos + 2]; // R通道 pix[i*4 + 1] = decodeBuf[bufPos + 1]; // G通道 pix[i*4 + 2] = decodeBuf[bufPos + 0]; // B通道 pix[i*4 + 3] = decodeBuf[bufPos + 3]; // A通道固定0xFF }
存在行对齐填充的场景:
部分解码库输出的像素数据每行末尾会有对齐填充字节,需按行拷贝:
int vidWidth = 你的视频宽度; int vidHeight = 你的视频高度; int lineStride = 解码库输出的单像素行字节数; unsigned char* decodeBuf = 解码库输出的RGB32字节数组指针; ofPixels pix; pix.allocate(vidWidth, vidHeight, OF_PIXELS_RGBA); for (int y = 0; y < vidHeight; y++) { unsigned char* srcLine = decodeBuf + y * lineStride; unsigned char* dstLine = pix.getPixels() + y * vidWidth * 4; memcpy(dstLine, srcLine, vidWidth * 4); }
注意事项
- ofTexture加载不同像素格式的ofPixels时,会自动适配GPU纹理格式,不需要额外做颜色空间转换,性能损耗极低
- 逐像素转换仅推荐在分辨率较低的场景使用,1080P及以上分辨率优先使用零拷贝方案或按行memcpy方案
内容的提问来源于stack exchange,提问作者NirG
相关产品推荐
相关产品推荐

