在这个问题上,我主要是寻求对C语言绘制GTK +和Cairo的一些概念的整体理解的建议和指导(IMO的主题信息相当匮乏,我的经验也很有限)。
我正在编码一些宠物应用程序,该应用程序从网络摄像头捕获帧并将其显示在GTK窗口中。
我的应用程序正在运行,但是有些地方我感觉不太好。
总体流程:
我有一个摄像头框架,是从摄像头设备映射到应用程序的进程内存的字节数组。因此,当捕获另一帧时,我拥有的是一个640 * 480 * 3字节长的数组,该数组表示为RGB24格式。经过一些搜索之后,为了将其显示在GTK窗口中,我需要使用gtk_drawing_area_new()创建一个称为绘图区域的对象,添加“绘制”回调并在指定的回调中进行“绘制”。因此,根据开罗的说法,“绘图”是将“来源”应用于“目标”的过程。我假设我已经有一个来源-我的网络摄像头mmaped像素,但看起来我需要使用一些开罗能够理解的“来源”。我找到了一个候选人:
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]
}
在此之后,我应该使用以下方法进行“绘制”:
cairo_set_source_surface(cr, surface, 0, 0);
cairo_paint(cr);
所以问题:
是应该为手头的任务做些什么还是我想念
这里完全有东西吗?
让我感到困惑的是我应该
重新布置我的原始网络摄像头像素,以捕获每个帧(此
大概会消耗一些CPU时间,可能是
以高帧率捕获高清分辨率)。还有其他方法吗?
假设我以某种方式从开罗的摄像头获取像素
符合格式,例如640x480x4 BGRA格式化的字节。有没有
在某些开罗可接受对象中“包装”此数据的方法以排除
像素重排部分?
还有其他我应该考虑的想法吗?
感谢您的关注。
最佳答案
对于您的大多数问题:开罗仅支持某些图像格式。由于您的数据采用其他格式,因此您必须对其进行转换。所有这些复制可能会太慢。为了使此工作以可接受的速度进行,您需要其他方法。不,我这里没有任何有用的建议。
一个无益的例子是:您可以看看此网络摄像头的一些示例吗?
假设我以某种方式以开罗格式从网络摄像头获取像素,例如640x480x4 BGRA格式化的字节。有没有一种方法可以将这些数据“包装”在一些开罗可接受的对象中,以排除像素重排部分?
对。 cairo_image_surface_create_for_data
。
关于c - 在C中使用GTK +和Cairo寻求有关网络摄像头图片显示的指导,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55542863/