Как использовать mutable_image элемент управления
Если необходимо отобразить на экране данные видео или кадры, снятые с помощью камеры, можно использовать элемент управления mutable_image. Этот элемент предоставляет функцию mutable_image_set_prepare_image, которая регистрирует функцию обратного вызова. Эта функция вызывается перед каждым рендерингом для подготовки изображения следующего кадра.
При использовании элемента управления mutable_image обычно используются следующие функции:
(1) Функция mutable_image_set_prepare_image:
/**
* @method mutable_image_set_prepare_image
* Устанавливает функцию prepare_image обратного вызова.
*
* Функция prepare_image обратного вызова вызывается перед каждым рендерингом для подготовки следующего кадра изображения. Например, получение предварительного просмотра с камеры и установка его в параметр image.
*
* Примечание: В функции обратного вызова можно изменять только содержимое изображения, но не его размер и формат. Если они не совпадают, сначала выполните преобразование.
*
* @param {widget_t*} widget Объект mutable_image.
* @param {mutable_image_prepare_image_t} prepare_image Функция обратного вызова для подготовки изображения.
* @param {void*} prepare_image_ctx Контекст функции обратного вызова.
*
* @return {ret_t} Возвращает RET_OK в случае успеха, иначе — ошибку.
*/
ret_t mutable_image_set_prepare_image(widget_t* widget,
mutable_image_prepare_image_t prepare_image, void* prepare_image_ctx);
Определение mutable_image_prepare_image_t:
typedef ret_t (*mutable_image_prepare_image_t)(void* ctx, bitmap_t* image);
(2) Функция bitmap_create_ex:
/**
* @method bitmap_create_ex
* Создаёт объект изображения.
* @annotation ["constructor", "scriptable", "gc"]
* @param {uint32_t} w Ширина.
* @param {uint32_t} h Высота.
* @param {uint32_t} line_length Фактическая память, занимаемая каждой строкой, обычно равна w * bpp, но можно указать значение по умолчанию 0.
* @param {bitmap_format_t} format Формат.
*
* @return {bitmap_t*} Возвращает объект bitmap.
*/
bitmap_t* bitmap_create_ex(uint32_t w, uint32_t h, uint32_t line_length,
bitmap_format_t format);
Формат параметра bitmap_format_t — это константа формата растрового изображения:
Имя | Описание |
---|---|
BITMAP_FMT_NONE | Недействительный формат |
BITMAP_FMT_RGBA8888 | Один пиксель занимает 4 байта, RGBA занимает один байт, увеличивается по адресу памяти |
BITMAP_FMT_ABGR8888 | Один пиксель занимает 4 байта, ABGR занимает один байт, увеличивается по адресу памяти |
BITMAP_FMT_BGRA8888 | Один пиксель занимает 4 байта, BGRA занимает один байт, увеличивается по адресу памяти |
BITMAP_FMT_ARGB8888 | Один пиксель занимает 4 байта, ARGB занимает один байт, увеличивается по адресу памяти |
BITMAP_FMT_RGB565 | Один пиксель занимает 2 байта, RGB занимает 5, 6 и 5 бит соответственно, увеличивается по адресу памяти |
BITMAP_FMT_BGR565 | Один пиксель занимает 2 байта, BGR занимает 5, 6 и 5 бит соответственно, увеличивается по адресу памяти |
BITMAP_FMT_RGB888 | Один пиксель занимает 3 байта, RGB занимает один байт, увеличивается по адресу памяти |
BITMAP_FMT_BGR888 | Один пиксель занимает 3 байта, RGB занимает один байт, увеличивается по адресу памяти |
BITMAP_FMT_GRAY | Один пиксель занимает 1 байт |
BITMAP_FMT_MONO | Один пиксель занимает 1 бит |
(3) Функция image_fill:
/**
* @method image_fill
* Рисует заданную область указанным цветом.
* @param {bitmap_t*} dst Целевой объект изображения.
* @param {const rect_t*} dst_r Область для заполнения.
* @param {color_t} c Цвет.
*
* @return {ret_t} Возвращает RET_OK при успехе, иначе — ошибку, в случае ошибки верхний уровень использует программную реализацию.
*/
ret_t image_fill(bitmap_t* dst, rect_t* dst_r, color_t c);
(4) Функция image_copy:
/**
* @method image_copy
* Копирует указанную область изображения в framebuffer.
* @param {bitmap_t*} dst Целевой объект изображения.
* @param {bitmap_t*} src Исходный объект изображения.
* @param {const rect_t*} src_r Область копирования.
* @param {xy_t} dx Координата x целевого положения.
* @param {xy_t} dy Координата y целевого положения.
*
* @return {ret_t} Возвращает RET_OK при успехе, иначе — ошибку, в случае ошибки верхний уровень использует программную реализацию.
*/
ret_t image_copy(bitmap_t* dst, bitmap_t* src, rect_t* src_r, xy_t dx, xy_t dy);
Можно использовать элемент управления mutable_image двумя способами. Оба способа выполняют одну и ту же функцию — устанавливают цвет экрана на синий. Результат показан на рисунке ниже:
Непосредственно работать с данными растрового изображения image_data, а затем установить соответствующие значения цвета в image_data. Размер image_data равен высоте растрового изображения, умноженной на bitmap_get_line_length (фактическая память, занятая каждой строкой, обычно равна ширине растрового изображения * bpp, где bpp — количество байтов, используемых одним пикселем). Формат данных растрового изображения должен соответствовать формату текущего LCD. Вы можете вызвать функцию lcd_get_desired_bitmap_format, чтобы получить текущий формат растровых данных LCD:
bitmap_format_t format = lcd_get_desired_bitmap_format(c->lcd);
Определение bitmap_format_t можно найти в приведённом выше описании параметра format или в файле awtk/src/base/types_def.h
.
image_data[0] = 0x1f; //Первый пиксель
image_data[1] = 0x00; //Первый пиксель
image_data[2] = 0x1f; //Второй пиксель
image_data[3] = 0x00; //Второй пиксель
...
... **Перевод текста на русский язык:**
В AWTK по умолчанию используется формат LCD BGR565, соответствующий формат данных см. на рисунке ниже:
| B | G | R |
|:--:|:--:|:--:|
| 5 | 6 | 5 |
Реализация кода следующая:
```c
ret_t mutable_image_prepare_image(void* ctx, bitmap_t* image) {
uint32_t i = 0;
uint32_t bpp = 0;
uint32_t size = 0;
uint8_t* image_data = NULL;
bpp = bitmap_get_bpp(image);
size = image->h * bitmap_get_line_length(image);
image_data = bitmap_lock_buffer_for_write(image);
/*
* LCD использует формат BGR565 ,тогда bpp должно быть равно 2
* image_data — это данные растрового изображения mutable_image, формат данных соответствует формату LCD
* размер image_data равен image->h * bitmap_get_line_length (каждая строка фактически занимает память, обычно это w*bpp)
* здесь мы устанавливаем image_data в синий цвет, конечно, можно также установить данные с камеры или видеоданные
*/
for (; i < size; i += bpp, image_data += bpp) {
image_data[0] = 0x1f;
image_data[1] = 0x00;
}
return RET_OK;
}
ret_t application_init() {
tk_ext_widgets_init();
widget_t* win = window_create(NULL, 0, 0, 0, 0);
/* создать mutable_image виджет */
widget_t* mutable = mutable_image_create(win, 0, 0, win->w, win->h);
/* зарегистрировать функцию обратного вызова для подготовки изображения mutable_image */
mutable_image_set_prepare_image(mutable, mutable_image_prepare_image, NULL);
return RET_OK;
}
Вызов bitmap_create_ex для создания объекта изображения, после создания объекта изображения вызовите функцию image_fill для заполнения объекта изображения значением цвета. Наконец, вызовите функцию image_copy, чтобы скопировать изображение, которое будет отображаться, в целевой объект изображения (объект изображения автоматически генерируется и уничтожается mutable_image виджетом), код следующий:
static ret_t mutable_image_prepare_image(void* ctx, bitmap_t* image) {
bitmap_t* src = (bitmap_t*)ctx;
rect_t r = rect_init(0, 0, image->w, image->h);
color_t color;
color.rgba.r = 0;
color.rgba.g = 0;
color.rgba.b = 0xff;
color.rgba.a = 0xff;
image_fill(src, &r, color);
image_copy(image, src, &r, 0, 0);
return RET_OK;
}
ret_t application_init() {
widget_t* mutable_image = NULL;
bitmap_t* src = NULL;
widget_t* win = window_create(NULL, 0, 0, 0, 0);
canvas_t* c = widget_get_canvas(win);
/* XXX: декодировать формат изображения и формат lcd должны совпадать, чтобы достичь максимальной производительности */
bitmap_format_t format = lcd_get_desired_bitmap_format(c->lcd);
src = bitmap_create_ex(win->w, win->h, 0, format);
mutable_image = mutable_image_create(win, 0, 0, win->w, win->h);
mutable_image_set_prepare_image(mutable_image, mutable_image_prepare_image, src);
return RET_OK;
}
Полный пример см. в mutable_image.c.
На некоторых платформах поддерживается несколько аппаратных FrameBuffer для LCD, эти аппаратные FrameBuffer могут быть объединены при аппаратном рендеринге для отображения на LCD, их можно понимать как несколько слоёв, слои объединяются после рендеринга на LCD. Этот метод намного быстрее, чем программное объединение, поэтому mutable_image также поддерживает использование слоёв аппаратного обеспечения.
Примечание: использование слоёв аппаратного обеспечения применимо только к платформам, поддерживающим несколько аппаратных FrameBuffer для LCD.
Использование слоёв аппаратного обеспечения требует выполнения следующих условий:
Следует отметить следующее:
Слой аппаратного обеспечения отличается от основного использования следующими тремя моментами:
После вызова функции mutable_image_set_framebuffer для настройки аппаратного FrameBuffer mutable_image не будет отображаться в графическом интерфейсе AWTK, но поскольку функция обновления mutable_image зависит от механизма обработки сообщений AWTK, частота кадров mutable_image такая же, как у AWTK. Преимущество состоит в том, что пользователю нужно только обновить данные изображения на mutable_image, а затем AWTK обработает остальное, код выглядит следующим образом:
/* Предположим, что макрос DEVICE_FB имеет адрес lcd аппаратного framebuffer */
#define DEVICE_FB (uint8_t*)0XC0000000
ret_t mutable_image_prepare_image(void* ctx, bitmap_t* image) {
uint32_t i = 0;
uint32_t bpp = 0;
uint32_t size = 0;
uint8_t* image_data = NULL;
bpp = bitmap_get_bpp(image);
size = image->h * bitmap_get_line_length(image);
image_data = bitmap_lock_buffer_for_write(image);
/*
* Заполнить синий цвет в аппаратный FrameBuffer LCD
* image_data - это растровое изображение mutable_image
* Здесь формат и размеры image соответствуют настройкам в функции mutable_image_set_framebuffer
* Здесь image_data устанавливается синим цветом, конечно, также можно установить данные камеры или видео
* Адрес image_data здесь - это адрес аппаратного FrameBuffer выше
*/
for(;i < size; i += bpp, image_data += bpp) {
image_data[0] = 0xff;
image_data[1] = 0x00;
image_data[2] = 0x00;
... ### 3.2 Прямое обновление аппаратного FrameBuffer
Если встраиваемая платформа поддерживает многопоточность, можно использовать один поток для отрисовки видеоданных на одном из аппаратных слоёв, а затем использовать другой поток для отрисовки графического интерфейса AWTK. Преимущество этого метода заключается в том, что частота обновления видео не будет зависеть от частоты кадров AWTK, и даже если графический интерфейс AWTK будет тормозить, это не повлияет на видео.
Поскольку элемент управления mutable_image поддерживает только изображения в форматах RGBA8888, BGRA8888, RGB888, BGR888, RGB565 и BGR565, разработчикам необходимо преобразовать изображения YUV в поддерживаемый формат перед отображением их на элементе управления. Если аппаратный слой поддерживает передачу изображений различных форматов, например, YUV, то можно сэкономить время и ресурсы, затрачиваемые на преобразование формата.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )