1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/zlgopen-awtk

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
how_to_use_mutable_image.md 20 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 28.11.2024 22:52 91e8897

Как использовать mutable_image элемент управления

Если необходимо отобразить на экране данные видео или кадры, снятые с помощью камеры, можно использовать элемент управления mutable_image. Этот элемент предоставляет функцию mutable_image_set_prepare_image, которая регистрирует функцию обратного вызова. Эта функция вызывается перед каждым рендерингом для подготовки изображения следующего кадра.

1. Связанные функции

При использовании элемента управления 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);

2. Основные способы использования

Можно использовать элемент управления mutable_image двумя способами. Оба способа выполняют одну и ту же функцию — устанавливают цвет экрана на синий. Результат показан на рисунке ниже:

Пример использования mutable_image элемента управления

2.1 Пример один

Непосредственно работать с данными растрового изображения 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.

  • Если format = BITMAP_FMT_BGR565, то один пиксель занимает два байта, и BGR занимает пять, шесть и пять битов соответственно, увеличиваясь по адресу памяти. Установите значения синего цвета в данных image_data следующим образом:
image_data[0] = 0x1f;   //Первый пиксель
image_data[1] = 0x00;   //Первый пиксель
image_data[2] = 0x1f;   //Второй пиксель
image_data[3] = 0x00;   //Второй пиксель
...
  • Если format = BITMAP_FMT_BGRA8888, то один пиксель занимает четыре байта, а BGRA занимает один байт и увеличивается по адресу памяти. Значения синего цвета в данных image_data устанавливаются следующим образом:
... **Перевод текста на русский язык:**

В 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;
}

2.2 Пример два

Вызов 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.

3 Использование слоёв аппаратного обеспечения для слияния изображений

На некоторых платформах поддерживается несколько аппаратных FrameBuffer для LCD, эти аппаратные FrameBuffer могут быть объединены при аппаратном рендеринге для отображения на LCD, их можно понимать как несколько слоёв, слои объединяются после рендеринга на LCD. Этот метод намного быстрее, чем программное объединение, поэтому mutable_image также поддерживает использование слоёв аппаратного обеспечения.

Примечание: использование слоёв аппаратного обеспечения применимо только к платформам, поддерживающим несколько аппаратных FrameBuffer для LCD.

Использование слоёв аппаратного обеспечения требует выполнения следующих условий:

  • Тип LCD в AWTK должен быть 32-битным RGBA или BGRA;
  • Определить макрос WITH_LCD_CLEAR_ALPHA, чтобы позволить AWTK поддерживать обновление прозрачных областей и поддерживать алгоритм смешивания с прозрачным фоном.

Следует отметить следующее:

  1. Определение макроса WITH_LCD_CLEAR_ALPHA снижает производительность AWTK;
  2. AWTK поддерживает обновление прозрачных областей, то есть поддерживает эффект полупрозрачного или полупрозрачного фона окна, его принцип заключается в том, что перед рисованием в прямоугольной области рисуется слой полностью прозрачного цвета;
  3. AWTK поддерживает алгоритм смешивания с прозрачным фоном, этот алгоритм потребляет больше ресурсов, чем алгоритм смешивания с непрозрачным фоном (фон прозрачный, необходимо добавить несколько операций умножения и деления для каждого пикселя точки, но если фон сам по себе не прозрачный, он деградирует до исходного алгоритма смешивания с непрозрачным фоном).

3.1 Пример

Слой аппаратного обеспечения отличается от основного использования следующими тремя моментами:

  • Слой аппаратного обеспечения должен использовать тип LCD 32-бит RGBA или BGRA;
  • Необходимо иметь адрес LCD аппаратного FrameBuffer, который обычно указывается платформой;
  • Вызов функции mutable_image_set_framebuffer для установки аппаратного FrameBuffer.

После вызова функции 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 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/zlgopen-awtk.git
git@api.gitlife.ru:oschina-mirror/zlgopen-awtk.git
oschina-mirror
zlgopen-awtk
zlgopen-awtk
master