在 C 中使用 GTK+ 和 Cairo 寻求有关网络摄像头图片显示的一些指导
Seeking some guidance on webcam picture display using GTK+ and Cairo in C
在这个问题中,我主要寻求建议和指导,以全面理解使用 C 语言使用 GTK+ 和 Cairo 进行绘图的一些概念(IMO,关于该主题的信息相当稀缺,我的经验也非常有限)。
我正在编写一些宠物应用程序,它从网络摄像头捕获帧并将它们显示在 GTK window 上。
我的应用程序可以正常运行,但有些地方我不太理解。
整体流程:
我有一个网络摄像头帧作为字节数组,从网络摄像头设备映射到我的应用程序的进程内存。因此,当捕获另一帧时,我所拥有的是一个 640*480*3 字节长的数组,表示为 RGB24 格式。经过一些搜索后,它看起来像是为了在 GTK window 中显示它,我需要使用 gtk_drawing_area_new() 创建一个名为绘图区域的对象,添加一个 "draw" 回调并执行 "drawing" 那里有一个指定的回调。所以,根据 Cairo 的说法,"drawing" 是一个将 "source" 应用到 "destination" 的过程。我假设我已经有了一个来源——我的网络摄像头 mmaped 像素,但看起来我需要使用一些 Cairo 能够理解的 "source"。我找到了一个候选人:
cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, 640, 480);
正如我所见,这个调用创建了一些 Cairo 可接受的对象,它在我的应用程序内存中分配了一个缓冲区,我可以使用:
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]
}
之后我应该 "drawing" 做:
cairo_set_source_surface(cr, surface, 0, 0);
cairo_paint(cr);
所以问题:
- 这是手头任务应该完成的还是我想念的
这里有什么东西?
- 让我困惑的是我应该
为捕获的每一帧重新排列我的原始网络摄像头像素(这
大概会消耗一些 cpu 时间,可能是一个限制因素
以高帧率捕获高清分辨率)。还有其他方法吗?
- 假设我以某种方式从开罗的网络摄像头获取了像素
符合格式,例如640x480x4 BGRA 格式字节。有没有
"wrap" 某些 Cairo 可接受对象中的此数据要排除的方法
像素重排部分 ?
- 还有其他我应该考虑的想法吗?
感谢关注。
对于您的大部分问题: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 进行绘图的一些概念(IMO,关于该主题的信息相当稀缺,我的经验也非常有限)。
我正在编写一些宠物应用程序,它从网络摄像头捕获帧并将它们显示在 GTK window 上。 我的应用程序可以正常运行,但有些地方我不太理解。
整体流程:
我有一个网络摄像头帧作为字节数组,从网络摄像头设备映射到我的应用程序的进程内存。因此,当捕获另一帧时,我所拥有的是一个 640*480*3 字节长的数组,表示为 RGB24 格式。经过一些搜索后,它看起来像是为了在 GTK window 中显示它,我需要使用 gtk_drawing_area_new() 创建一个名为绘图区域的对象,添加一个 "draw" 回调并执行 "drawing" 那里有一个指定的回调。所以,根据 Cairo 的说法,"drawing" 是一个将 "source" 应用到 "destination" 的过程。我假设我已经有了一个来源——我的网络摄像头 mmaped 像素,但看起来我需要使用一些 Cairo 能够理解的 "source"。我找到了一个候选人:
cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, 640, 480);
正如我所见,这个调用创建了一些 Cairo 可接受的对象,它在我的应用程序内存中分配了一个缓冲区,我可以使用:
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]
}
之后我应该 "drawing" 做:
cairo_set_source_surface(cr, surface, 0, 0);
cairo_paint(cr);
所以问题:
- 这是手头任务应该完成的还是我想念的 这里有什么东西?
- 让我困惑的是我应该 为捕获的每一帧重新排列我的原始网络摄像头像素(这 大概会消耗一些 cpu 时间,可能是一个限制因素 以高帧率捕获高清分辨率)。还有其他方法吗?
- 假设我以某种方式从开罗的网络摄像头获取了像素 符合格式,例如640x480x4 BGRA 格式字节。有没有 "wrap" 某些 Cairo 可接受对象中的此数据要排除的方法 像素重排部分 ?
- 还有其他我应该考虑的想法吗?
感谢关注。
对于您的大部分问题: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
.