В этом вопросе я в основном ищу советы и рекомендации по общему пониманию некоторых концепций рисования с GTK + и Cairo на языке Си (ИМО, информация по теме довольно скудная, а также мой опыт в действительно скромном).
Я пишу какое-то приложение для домашних животных, которое захватывает кадры с веб-камеры и отображает их в окне GTK.Мое приложение работает, но есть некоторые моменты, которые мне не совсем понятны.
Общий процесс:
У меня есть кадр веб-камеры в виде массива байтов mmapedс устройства веб-камеры в оперативную память моего приложения.Поэтому, когда захватывается другой кадр, получается массив длиной 640 * 480 * 3 байта, который обозначается как формат RGB24.После некоторого поиска он выглядит так, чтобы отображать его в окне GTK. Мне нужно создать объект, называемый областью рисования, с помощью gtk_drawing_area_new (), добавить обратный вызов «draw» и выполнить там «рисование» в назначенном обратном вызове.Итак, согласно Каиру «рисование» - это процесс применения «источника» к «месту назначения».Я предполагаю, что у меня уже есть источник - моя веб-камера mmaped пикселей, но, похоже, мне нужно использовать какой-то «источник», который Каир способен понять.Я нашел кандидата:
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);
Итак, вопросы:
- Это то, что должно быть сделано для выполнения поставленной задачи, или я что-то здесь упускаю полностью?
- Что меня смущает, так это то, что мне нужно переставить исходные пиксели веб-камеры для КАЖДОГО захваченного кадра (это, вероятно, потребляет некоторое время процессора, может быть ограничивающим фактором для захвата в разрешении HD при высокой частоте кадров).Есть какой-то другой способ?
- Давайте предположим, что я каким-то образом получаю пиксели с веб-камеры в формате, соответствующем Каиру, например, 640x480x4 отформатированных байтов BGRA.Есть ли способ «обернуть» эти данные в какой-нибудь приемлемый для Каира объект, чтобы исключить переупорядочение элементов изображения?
- Есть еще какие-нибудь мысли, которые я должен был рассмотреть?
Спасибо за внимание.