在C中使用GTK +和Cairo寻求关于网络摄像头图片显示的一些指导

问题描述 投票:0回答:1

在这个问题中,我主要是寻求建议和指导,以全面理解用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字节长的缓冲区,在一个小的endian archs上,应该填充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);

所以问题:

  1. 是应该为手头的任务做什么,还是我完全错过了这里的东西?
  2. 令我困惑的是,我应该重新安排我的原始网络摄像头像素,以捕获每个帧(这可能会消耗一些CPU时间,可能是以高帧率捕获高清分辨率的限制因素)。还有其他方法吗?
  3. 假设我以某种方式从开头符合格式的网络摄像头获取像素,例如, 640x480x4 BGRA格式化字节。有没有办法在一些开罗可接受的对象中“包装”这些数据以排除像素重新排列部分?
  4. 我还应该考虑其他任何想法吗?

谢谢你的关注。

c gtk rgb webcam cairo
1个回答
1
投票

对于您的大部分问题:Cairo仅支持某些图像格式。由于您的数据采用其他格式,因此您必须进行转换。所有这些复制可能会太慢。要以可接受的速度完成这项工作,您需要一些其他方法。不,我这里没有任何有用的建议。

一个无用的问题是:你可以看一下这个网络摄像头的例子吗?

假设我以某种方式从开头符合格式的网络摄像头获取像素,例如, 640x480x4 BGRA格式化字节。有没有办法在一些开罗可接受的对象中“包装”这些数据以排除像素重新排列部分?

对。 cairo_image_surface_create_for_data

© www.soinside.com 2019 - 2024. All rights reserved.