Edit online

Blending

5 Dec 2024
Read time: 6 minute(s)

对于显示引擎 (Display Engine) 支持一个 UI 图层和一个 Video 图层的产品系列,可以使用 blending 功能,将两个或多个图像图层以某种方式结合在一起,以产生新的图像效果。在 UI 图层和 Video 图层重叠的区域,可以进行 Color Key 操作和 Alpha 叠加操作,其中 Color Key 操作优先于 Alpha 叠加。

Alpha Blending

Alpha 叠加涉及到使用 alpha 通道来确定图像的透明度级别。Alpha 值通常在 0 到 255 之间,其中 0 表示完全透明,255 表示完全不透明。通过调整 alpha 值,可以控制图层之间的混合程度。
注:

Video 图层不支持配置 Alpha。

UI alpha 包含以下多种模式:

  1. pixels alpha 模式:默认模式,根据像素 alpha 值确定透明度,ui_alpha = pixel_alpha, 当 pixel alpha 不存在时,ui_alpha = 255。

  2. 全局 alpha 模式:使用统一的 G_ALPHA 值,ui_alpha = G_ALPHA,G_ALPHA 为设置的全局 alpha 值,取值范围为 0~255

  3. 混合 alpha 模式:将两者结合的模式,ui_alpha = pixels alpha * G_ALPHA / 255

UI 图层和 Video 图层透明度混合计算:
r_out = (r_ui * alpha_ui + r_video * (255 - alpha_ui))/255
g_out = (g_ui * alpha_ui + g_video * (255 - alpha_ui))/255
b_out = (b_ui * alpha_ui + b_video * (255 - alpha_ui))/255
数据结构
#define AICFB_PIXEL_ALPHA_MODE      0
#define AICFB_GLOBAL_ALPHA_MODE     1
#define AICFB_MIXDER_ALPHA_MODE     2

/**
 * struct aicfb_alpha_config - aicfb layer alpha blending config
 *
 * @layer_id: the layer id
 *
 * @enable
 *  0: disable alpha
 *  1: enable alpha
 *
 * @mode: alpha mode
 *  0: pixel alpha mode
 *  1: global alpha mode
 *  2: mixder alpha mode(alpha = pixel alpha * global alpha / 255)
 *
 * @value: global alpha value (0~255)
 *  used by global alpha mode and mixer alpha mode
 *
 */
struct aicfb_alpha_config {
    unsigned int layer_id;
    unsigned int enable;
    unsigned int mode;
    unsigned int value;
};

/** get layer alpha blendig config */
#define AICFB_GET_ALPHA_CONFIG  _IOWR(IOC_TYPE_FB, 0x26, \
                struct aicfb_alpha_config)

/** update layer alpha blendig config */
#define AICFB_UPDATE_ALPHA_CONFIG  _IOW(IOC_TYPE_FB, 0x27, \
                struct aicfb_alpha_config)
使用例程
static int set_ui_layer_alpha(int val)
{
    int ret = 0;
    struct aicfb_alpha_config alpha = {0};

    alpha.layer_id = AICFB_LAYER_TYPE_UI;
    alpha.mode     = AICFB_GLOBAL_ALPHA_MODE;
    alpha.enable   = 1;
    alpha.value    = val;
    ret = mpp_fb_ioctl(g_mpp_fb, AICFB_UPDATE_ALPHA_CONFIG, &alpha);
    if (ret < 0)
        ERR("ioctl update alpha config failed!\n");

    return ret;
}
常见问题及解决方法
  1. 默认配置下 Video 图层不显示 。

    Luban-Lite Lite SDK UI alpha 默认使用 pixel alpha 模式,检查是否启用了 alpha 配置,并确保 Video 图层的 alpha 模式正确。

    1. pixel alpha 为 0xFF

    2. framebuffer 缺失 alpha 分量

  2. Framebuffer RGB565/RGB888 格式设置 UI pixel alpha 模式不生效 。

    确保 framebuffer 格式支持 alpha 分量,例如,RGB565/RGB888 格式不支持 alpha,需要使用 RGBA8888 或其他支持 alpha 的格式。framebuffer 16/24 bit RGB 格式缺失 pixel alpha,ui_alpha 默认为 255,UI 图层不透明,Video 图层不可见。

Color Key

Color Key 用于通过指定一种颜色(通常是不常见的颜色,如绿色或蓝色),使得图像中的这种颜色变得透明,从而可以与其他图层进行合成。

通过设置 8 bit R,G,B 三原色进行 Color Key 操作:

数据结构
/**
 * struct aicfb_ck_config - aicfb layer color key blending config
 *
 * @layer_id: the layer id
 *
 * @ck_enable
 *  0: disable color key
 *  1: enable color key
 *
 *
 * @ck_value: color key rgb value to match the layer pixels
 *  bit[31:24]: reserved
 *  bit[23:16]: R value
 *  bit[15:8]: G value
 *  bit[7:0]: B value
 *
 */
struct aicfb_ck_config {
    unsigned int layer_id;
    unsigned int enable;
    unsigned int value;
};

/** get layer color key config */
#define AICFB_GET_CK_CONFIG  _IOWR(IOC_TYPE_FB, 0x28, struct aicfb_ck_config)

/** update layer color key config */
#define AICFB_UPDATE_CK_CONFIG  _IOW(IOC_TYPE_FB, 0x29, struct aicfb_ck_config)
使用例程
static int set_ui_color_key(unsigned char r, unsigned char g, unsigned char b)
{
    struct aicfb_ck_config ck = {0};
    int ret = 0;
    unsigned int val;

    val = (r << 16) | (g << 8) | (b << 0);

    ck.layer_id = AICFB_LAYER_TYPE_UI;
    ck.enable   = 1;
    ck.value    = val;
    ret = mpp_fb_ioctl(g_fb_fd, AICFB_UPDATE_CK_CONFIG, &ck);
    if (ret < 0)
        printf("ioctl() failed! errno: %d[%s]\n", errno, strerror(errno));

    return ret;
}
注:

Video 图层不支持配置 Color Key,确保仅在 UI 和 Video 图层的重叠区域进行 Color Key 操作。

RGB565 Color Key
缺失的 bit 需要循环移位补齐,比如 G 只有 6 bit,缺失的低 2 bit 用高位来补齐:
0b101111 > 0b10111110
0b10111  > 0b10111101
例如有一个 6-bit 的 G 值,需要补齐成 8-bit,则 g_extended 就是 0b10111110:
unsigned char g = 0b101111; // 原始 6-bit G 值
unsigned char g_extended = (g << 2) | (g >> 4); // 补齐到 8-bit