STemWin版本:544 (ST购买了emWin的license,可以在ST芯片中使用emWin工具包,就叫STemWin)
emWin开发工具包可以转换JPG、BMP、GIF等各种图像为数据文件,格式是以C语言的形式定义的数据结构。
在目标程序中再调用emWin的库函数,以转换后得到的图像数据为参数,将图像或动画显示到屏幕上。
不止于此,emWin还支持视频文件,支持两种格式,一种是专有格式EMF,另一种是AVI文件。
EMF缩写:(E)mWin (M)ovie (F)ile。
EMF文件实际上是单个JPEG文件的组合,开发包里有个JPEG2Movie的工具,可以把很多个JPEG文件组合成一个Movie文件。把这些JPEG图像文件放在一个文件夹里,每个图像就是movie的一帧。
AVI文件,Audio Video Interleave文件,这是微软发明的。
EMF要求:
EMF文件的显示是一帧帧来,所以内存里存放一帧的数据即可,再加上描画过程需要占用些内存。这个和一般的movie文件的描画方法是不同的。
为了支持EMF文件描画,相应功能的程序库功能大概占用22KB flash。
为了保证显示流畅,要保证每秒至少25帧。
AVI要求:
AVI文件的编码格式要是MJPEG,并且需要包含名为idx1的索引列表。
AVI里面可以包含音频,但这部分不会被emWin处理。
通过FFmpeg.exe创建JPEG文件:这是一个开源软件,使用LGPL或GPL协议,基本上能将各种movie文件转换为所需要的格式,包括单个的JPEG文件。
去官网www.ffmpeg.org下载。
然后在开发工具包里找到JPEG2MovieScripts文件夹,里面有个Prep.bat, MakeMovie.bat和<X_SIZE>x<Y_SIZE>.bat。
Prep.bat由MakeMovie.bat调用,里面设置一些变量,比如:
%OUTPUT% 输出文件夹
%FFMPEG% ffmpeg程序路径
%JPEG2MOVIE% JPEG2MOVIE程序的路径。
%DEFAULT_SIZE% 默认的影音文件分辨率,如果由某个<X_SIZE>x<Y_SIZE>.bat被指定则可以忽略。
%DEFAULT_QUALITY% 默认的影音质量,数字越小质量越高。1表示最好的JPEG图片转换质量。31是最差的。
%DEFAULT_FRAMERATE% 默认转换的每秒帧数。
MakeMovie.bat
这个是控制转换的主bat文件,一般情况下不用更改。需要更改Prep.bat即可。
调用这个bat文件需要一下几个参数:
%1 需要被转换的影音文件
%2 (optional) 转换的JPEG的图片分辨率,如果没指定就是用Prep.bat文件里面默认值。
%3 (optional) 指定图片转换质量,不指定就是用Prep.bat文件里面的默认值。
%4 (optional) 转换帧率。没指定就用默认。
执行MakeMovie.bat得到JPEG文件,然后使用JPEG2Movie创建一个EMF文件。
这个文件能被emWin直接使用。
AVI文件的制作和EMF文件类似。
JPEG转换后,得到一个文件夹,里面都是JPEG文件,运行JPEG2Movie.exe:
选择JPEG所在文件夹,帧率默认40ms每帧,然后转换。
转换后的结果,使用emWin Movie Player进行预览。
下面是播放EMF文件的样例代码:
#if defined(__ICCARM__)
#pragma location="ExtFlashSection"
#else
__attribute__((section(".ExtFlashSection")))
#endif
const unsigned char _acJPEG[1387422UL + 1] = {
....................................
};
void MainTask(void)
{
int errorcode = 0;
GUI_MOVIE_HANDLE handle=0;
GUI_MOVIE_INFO info;
/* Initialize the GUI */
GUI_Init();
errorcode = GUI_MOVIE_GetInfo(_acJPEG, 1387422UL, &info);
if(errorcode) return;
handle = GUI_MOVIE_Create(_acJPEG, 1387422UL, _cbNotify);
if(handle==0) return;
GUI_MOVIE_SetPeriod(handle, info.msPerFrame);
GUI_MOVIE_Show(handle, (LCD_GetXSize() - (info.xSize))/2 , (LCD_GetYSize() - (info.ySize) - 30)/2, 1);
while (1)
{
LCD_WaitForDisplayCompletion();
GUI_Exec1();
LCD_RefreshRequestedByApplicatyion();
LCD_WaitForDisplayCompletion();
GUI_Delay(50);
}
}
上面的代码请注意:
-
变量_acJPEG就是EMF文件的数据,使用生成的EMF文件通过工具包里的Bin2C.exe转换而成。
这个变量比较大,此处使用的是外部OctoSPI flash存储。也可以使用SD卡来存储这个文件,然后使用GUI_MOVIE_CreateEx来创建Movie handle。
-
使用OctoSPI flash可以直接访问外部flash数据,和使用内部flash一样,在线性地址空间中直接地址访问。
因为是外部flash,所以需要分配一个单独section,在文件头的pragma命令。
然后在(链接器)linker configuration里配置这个section,使链接后的hex或image文件能正确生成。
-
while(1)里面的代码,是负责GUI刷新,因为要显示动画,所以要不停刷新。
关于linker配置section的例子:
在IAR工程里使用的stm32l4r9xx_flash.icf文件的相关修改:
/*-Octo-SPI Memory Regions-*/
define symbol __ICFEDIT_region_OSPI_ML1_start__ = 0x90000000;
define symbol __ICFEDIT_region_OSPI_ML1_end__ = 0x9CFFFFFF; /* 2,24 Mbytes for the MB1314 MenuLauncher assets */
define region OSPI_ML1_region = mem:[from __ICFEDIT_region_OSPI_ML1_start__ to __ICFEDIT_region_OSPI_ML1_end__];
place in OSPI_ML1_region { section ExtFlashSection };