AWTK是基于C语言开发的跨平台GUI框架。《AWTK使用经验》系列文章将介绍开发AWTK过程中一些常见问题与解决方案,例如:如何加载外部资源?如何设计自定义进度条?这些都会在系列文章进行解答。
加载指定路径的图片资源
AWTK默认加载资源方式有两种,一种是将资源打包到程序中放入Flash,另一种是放在res资源目录中。假设现在需要实现一个图片浏览器并移植到 ZTP800示教器 设备上,该图片浏览器需要加载U盘图片,此时就要用到AWTK加载外部资源的功能来实现该需求。下面将分为有文件系统和无文件系统两种情况来介绍此功能。图1 ZTP800示教器加载U盘图片效果
1. 有文件系统
在有文件系统时若想加载非AWTK默认目录结构的图片资源,可以使用:file:// + 图片所在路径的形式来加载图片,并且可以使用C代码或者xml形式来加载。
1.1 C代码方式:
widget_t* image = widget_lookup(win, "image", TRUE);
image_set_image(image, "file:///media/sda1/AWTK.png");
1.2 XML方式:
<window name="home_page ">
<image name="image" x="0" y="0" w="50" h="50" draw_type="default" image="file:///media/sda1/AWTK.png"/>
</window>
2. 无文件系统
若是在没有文件系统的设备中加载外部图片,可以先读取图片文件数据,再将数据作为参数传给 assets_manager_add_data() 函数。该函数会将数据添加到AWTK资源管理器中,添加后就可以通过文件名的形式来显示图片了。
下面是一段STM32平台加载SD卡图片的示例代码:
uint8_t read_buffer[512];
int sdcard_status = HAL_SD_ReadBlocks(&sd_handle, (uint8_t*) read_buffer, 0, 1, 0xffff);
if (sdcard_status == HAL_OK) {
assets_manager_add_data(assets_manager(),"AWTK",ASSET_TYPE_IMAGE,ASSET_TYPE_IMAGE_PNG, read_buffer, size);
image_set_image(image, "AWTK");
}
释放图片资源并重新加载
假设目前实现了图片浏览器并移植到了ZTP800示教器上,但是需要图片浏览器加载的图片名称固定不变,而本地图片数据会经常发生改变,这时候就需要在AWTK重新加载并更新图片到画面中。
AWTK在加载一张图片时,会先将图片缓存到assets_manager资源管理器当中,接着再解码放到image_manager图片管理器,最后显示的图片来自图片管理器解码好的图片,因此对于上面的需求就要手动卸载与重新加载图片缓存。下图为ZTP800示教器上的示例程序重新加载图片前后效果图:
图2 示例程序的初始图
图2 示例程序的初始图
1. 卸载图片缓存
假设在示例程序中已经加载并显示了一张图片,并且此时本地图片文件数据发生了改变,可以按照以下步骤卸载图片管理器和资源管理器上的图片缓存。
#define IMAGE_NAME "/media/sda1/AWTK.png" // 图片名默认为assets_manager_load_file加载的路径
static ret_t on_unload_button_click(void* ctx, event_t* e) { // 点击卸载图片按钮卸载图片缓存
bitmap_t bitmap = {0};
widget_t* win = WIDGET(ctx);
widget_t* image = widget_lookup(win, "image", TRUE);
// 卸载图片管理器缓存
image_manager_get_bitmap(image_manager(), IMAGE_NAME, &bitmap);
image_manager_unload_bitmap(image_manager(), &bitmap);
// 卸载资源管理器缓存
assets_manager_clear_cache_ex(assets_manager(), ASSET_TYPE_IMAGE, IMAGE_NAME);
widget_invalidate(image, NULL);
return RET_OK;
}
上面代码中image_manager_unload_bitmap是用于卸载图片在图片管理器的缓存卸载缓存成功后会输出“unload image xxx”的debug信息;assets_manager_clear_cache_ex是用于卸载资源管理器的该图片缓存。
2. 重新加载图片缓存
卸载图片缓存后,可以通过以下步骤再次加载图片到资源管理器中:
static ret_t on_load_button_click(void* ctx, event_t* e) { // 点击加载图片按钮重新加载图片缓存
widget_t* win = WIDGET(ctx);
widget_t* image = widget_lookup(win, "image", TRUE);
// 将新的图片数据添加到资源管理器缓存中
asset_info_t* img = assets_manager_load_file(assets_manager(), ASSET_TYPE_IMAGE, IMAGE_NAME);
assets_manager_add(assets_manager(), img);
image_set_image(image, IMAGE_NAME);
widget_invalidate(image, NULL);
return RET_OK;
}
上面代码调用assets_manager_load_file与assets_manager_add重新加载了一次图片数据到AWTK资源管理器的缓存,此时加载的数据是新的图片数据。
后续在调用image_set_image以及widget_invalidate刷新图片控件时会自动将位于资源管理器的缓存解码并放到图片管理器当中,最后显示新的图片数据。