最近研究了一下AWTK (Toolkit AnyWhere)这个GUI。发现功能挺强大,为了感受一下这个与Minigui的差别,所以做了一个在视频流上面增加人脸跟随框的功能。
实现期间,发现两个GUI还是有一些差别,所以写个文档记录一下实现的方法。
下载代码与搭建环境的事情这里就不做赘述了。
1.开启宏WITH_LCD_CLEAR_ALPHA
因为我的是linux设备,所以修改awtk-linux-fb目录下的awtk_config.py文件,增加
宏定义:
COMMON_CCFLAGS=COMMON_CCFLAGS+' -DWITH_LCD_CLEAR_ALPHA '
如果不知道位置在哪里,文件里搜索COMMON_CCFLAGS关键字,在后面追加即可。
2.设置窗口背景色
在窗口初始化的时候,需要把窗口的bg_color设置为透明的颜色。如:
widget_t* win = window_create(NULL, 0, 0, 0, 0);
cameraWin = canvas_widget_create(win, 0, 0, win->w, win->h);
widget_set_style_color(win, "bg_color", 0x00000000);
这里一开始的时候看文档,使用了这个接口设置:
widget_set_opacity(win, 0);
这个接口虽然可以把窗口设置为透明,但是后面无法正常画人脸框。所以不能使用这个接口。具体原因尚未研究。
3.使用离线画布绘制
我们这个业务场景是:视频流单独一个视层,独立于fb之外。gui创建在fb上面。在gui的应用中,需要显示视频流时,把窗口设置透明即可显示下面的视频流。
所以,我们的绘制人脸框的思路是:
清空画布 >> 绘制人脸框 >> 清空画布 >> 绘制人脸框…
初次实现,我们放在控件的paint事件中实现:
//离线画布
static ret_t on_paint_vgcanvas(void* ctx, event_t* e) {
widget_t* widget = WIDGET(e->target);
paint_event_t* evt = paint_event_cast(e);
/* 设置离线的 canvas 为当前绘图的画布 */
canvas_t* c = canvas_offline;
canvas_offline_clear_canvas(c); //清空画布,避免矩形框重叠
/* 获取离线的 canvas 对应的离线 bitmap */
bitmap_t* offline_bitmap = canvas_offline_get_bitmap(canvas_offline);
/* 开始离线 canvas 绘图 */
canvas_offline_begin_draw(canvas_offline);
vgcanvas_t* vg = canvas_get_vgcanvas(c);
vgcanvas_save(vg);
vgcanvas_set_line_width(vg, 5);
point_t leftTopCorner = {0};
leftTopCorner.x = faceRect.x;
leftTopCorner.y = faceRect.y;
widget_to_local(widget, &leftTopCorner);
vgcanvas_rect(vg, leftTopCorner.x, leftTopCorner.y, faceRect.w, faceRect.h);
vgcanvas_set_stroke_color(vg, color_init(0xff, 0xff, 0, 0xff));
vgcanvas_stroke(vg); //画线
vgcanvas_restore(vg);
/* 结束离线 canvas 绘图 */
canvas_offline_end_draw(canvas_offline);
/* 把显存中的 bitmap 显示到在线的 canvas 中 */
rect_t r = rect_init(0, 0, offline_bitmap->w, offline_bitmap->h);
canvas_draw_image_ex(evt->c, offline_bitmap, IMAGE_DRAW_DEFAULT, &r);
return RET_OK;
}
实现前期,一直使用画布与在线画布,想着每次使用透明色填充整个控件的矩形来清空画布,发现这样做是不行的,无法清空背景。而且,窗口的背景色也需要设置。