在这个问题中,我主要寻求关于用 C 语言使用 GTK+ 和 Cairo 绘图的一些概念的整体理解的建议和指导(IMO 有关该主题的信息相当稀缺,而且我的经验也非常有限)。
我正在编写一些宠物应用程序,该应用程序从网络摄像头捕获帧并将其显示在 GTK 窗口上。 我的应用程序正在运行,但有一些地方我感觉不太明白。
<小时/>总体流程:
我有一个网络摄像头帧,作为从网络摄像头设备映射到我的应用程序进程内存的字节数组。因此,当捕获另一个帧时,我得到的是一个 640*480*3 字节长的数组,它表示为 RGB24 格式。经过一番搜索后,似乎为了在 GTK 窗口中显示它,我需要使用 gtk_drawing_area_new() 创建一个名为绘图区域的对象,添加一个“绘图”回调并在指定的回调中进行“绘图”。所以,根据开罗的说法,“绘图”是一个将“源”应用到“目的地”的过程。我假设我已经有一个源 - 我的网络摄像头映射像素,但看起来我需要使用开罗能够理解的一些“源”。我找到了一位候选人:
cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, 640, 480);
正如我所见,这个调用创建了一些开罗可接受的对象,它一路上在我的应用程序内存中分配了一个缓冲区,我可以使用以下方法获取该缓冲区:
unsigned char* surface_data = cairo_image_surface_get_data(surface);
根据文档,这是一个 640x480x4 字节长的缓冲区,在小端架构上,应该填充 BGRA 格式的像素数据。 然后我应该为使用此捕获的每个帧重新排列原始网络摄像头像素:
for (size_t idx_src=0, idx_dst=0; idx_src<640*480*3; idx_dst+=4, idx_src+=3) {
surface_data[idx_dst] = image[idx_src+2]; //B [3rd pos -> 1st pos]
surface_data[idx_dst+1] = image[idx_src+1]; //G [no change]
surface_data[idx_dst+2] = image[idx_src]; //R [1st pos -> 3rd pos]
}
之后我应该用以下方法“绘图”:
cairo_set_source_surface(cr, surface, 0, 0);
cairo_paint(cr);
<小时/>
所以问题:
- 这是手头任务应该完成的事情还是我错过了 这里完全有东西吗?
- 令我困惑的是我应该 为捕获的每个帧重新排列我的原始网络摄像头像素(这 大概会消耗一些CPU时间,可能是一个限制因素 以高帧速率进行高清分辨率捕获)。还有其他办法吗?
- 假设我以某种方式从开罗的网络摄像头获取像素 符合格式,例如640x480x4 BGRA 格式的字节。有没有 将此数据“包装”在一些开罗可接受的对象中以排除的方法 像素重新排列部分?
- 我还有其他应该考虑的想法吗?
感谢您的关注。
最佳答案
对于您的大多数问题:Cairo 仅支持某些图像格式。由于您的数据采用另一种格式,因此您必须对其进行转换。所有这些复制可能会太慢。为了使这项工作以可接受的速度进行,您需要一些其他方法。不,我这里没有任何有用的建议。
一个没有帮助的问题是:您可以看一下这个网络摄像头的一些示例吗?
Let's suppose I somehow acquire pixels from webcam in a Cairo conforming format, e.g. 640x480x4 BGRA formatted bytes. Is there a way to "wrap" this data in some Cairo acceptable object to exclude pixel rearranging part ?
是的。 cairo_image_surface_create_for_data
。
关于c - 寻求一些关于使用 GTK+ 和 Cairo C 语言显示网络摄像头图片的指导,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55542863/