转stemwin教程
本期主要讲emWin支持的BMP图片显示,官方支持的主要有两种显示方法,一种是从外部存储器读取数据到内部存储器然后来显示图片,这种的显示速度要快些,另一种方法是直接从外部存储器读取数据并显示,这种办法的好处就是不要大的RAM需求,每次读取一些数据显示一次,缺点就是显示速度比较的慢。
这里有一点必须的要说明一下,官方支持的这个BMP图片的显示速度没有咱们平时用的在TFT上面开窗然后填充图片数据的速度快,但是有一个非常大的好处就是使用官方的这个函数才能充分的发挥背景重绘等机制。
11. 1 BMP函数说明
11. 2 绘制已经加载到存储器的BMP图片
11. 3 绘制无须加载到存储器的BMP图片
11. 4 实验总结
11.1 BMP函数说明
关于BMP图片格式方面的知识,大家可以在google上面查找资料进行了解。这里重点的介绍一下STemWin对BMP图片的格式的支持。
对于一些频繁调用的BMP图片,大家可以用第9章上面说的位图转换器进行图片转换即可,只不过本期教程是将其转换成C文件。这里举两个例子,一个是转换一个带透明色的PNG格式图标,另一个是转换一张BMP格式的图片
11.1.1 PNG格式图标转BMP
这里我们演示的是如下带透明色的PNG图标,PNG格式的图标用到的地方还是非常多的,虽然用位图转换器(BmpCvt.exe)可以打开,但是转换后的C文件是不具备透明色效果的,这时得使用软件IconWorkshop进行转换(请使用正版软件),将其转换为32位带Alpha通道的BMP图片。
2
|
|
|
|
第一步:先用位图软件直接打开PNG格式的图标,打开后的效果如下:
对于带透明色的PNG图片,用位图转换器打开后是这种效果的,转换成C文件后显示出来是不正确的,得用软件IconWorkshop进行转换。
|
|
|
|
|
第二步:用软件IconWorkshop打开这个图标,打开后的效果如下:
然后将其另存为BMP格式的图片
|
|
|
|
|
第三步:再次用位图转换器打开上面转换好的BMP图片,打开后效果如下:
图片:11.5.jpg
打开是这种效果,转换后的C文件才能正常的显示。
|
|
|
|
|
点击另存为C文件后会出现如下的界面:
这里我们就选择第一个True color alpha chanel进行保存。点击OK后会生成C文件。生成的C文件保存在了这个图片所在的文件夹里面(注意是大家加载的这个BMP图片文件夹,不是位图软件文件夹)。
|
|
|
|
|
下面我们在emWin5.24模拟器上面显示一下我们刚才转换好的图标。
实际运行代码如下(图片数据就不贴出来了,看本期教程配套的例子)
复制代码
GUI_CONST_STORAGE GUI_BITMAP bm20140406102510816_easyicon_net_96 = {
96, // xSize
96, // ySize
384, // BytesPerLine
32, // BitsPerPixel
(unsigned char *)_ac20140406102510816_easyicon_net_96, // Pointer to picture data
NULL, // Pointer to palette
GUI_DRAW_BMP8888
};
void MainTask(void)
{
GUI_Init();
GUI_DrawBitmap(&bm20140406102510816_easyicon_net_96, 30, 30);
while(1)
{
GUI_Delay(100);
}
}
|
|
|
|
|
11.1.2 BMP格式图标转换
下面我们讲解一下BMP格式的位图转换。
l 第一步:比如我们要转如下所示的BMP图片。
|
|
|
|
|
第二步:这里我们做一次图片的格式转换,转换格式如下:
|
|
|
|
|
第三步:转换后,另存为C文件的格式如下:
图片:11.12.png
转换后生成的C文件和图片在同一个文件夹里面。下面我们在emWin5.24模拟器上面显示下这个图片
|
|
|
|
|
下面是模拟器上面实际运行的代码(图片数据没有贴,全部运行代码请看本期教程配套的例子)
复制代码
GUI_CONST_STORAGE GUI_BITMAP bm1 = {
480, // xSize
272, // ySize
960, // BytesPerLine
16, // BitsPerPixel
(unsigned char *)_ac1, // Pointer to picture data
NULL, // Pointer to palette
GUI_DRAW_BMP444_12
};
void MainTask(void)
{
GUI_Init();
GUI_DrawBitmap(&bm1, 30, 30);
while(1)
{
GUI_Delay(100);
}
}
|
|
|
|
|
下面是实际显示效果:
讲完这两个例子以后,大家应该对位图转换器的使用有所了解了。下面开始讲直接的显示BMP格式的图片。STemWin支持的API函数如下:
|
|
|
|
|
11.2 绘制已经加载到存储器的BMP图片
将图片加载到存储器后进行显示比较的耗内存,所以这里就使用开发板外置的2MB SRAM做STemWin的动态内存空间,并通过相应的API函数申请动态内存来加载SD卡等外部存储器中的BMP图片。申请和释放STemWin动态内存的方法如下:
[url=]复制代码[/url]
- /* 申请一块内存空间 并且将其清零 */
- hMem = GUI_ALLOC_AllocZero(100000);
- /* 将申请到内存的句柄转换成指针类型 */
- _acBuffer2 = GUI_ALLOC_h2p(hMem);
- /* 释放申请的动态内存 */
- GUI_ALLOC_Free(hMem);
比如我们要显示下面的BMP格式的图片:
就可以把这个图片放到SD卡中,然后通过程序把这个图片数据全部的加载到SRAM中,最后在屏上进行显示。这个工程的实现主要分为如下三个部分:
Ø SRAM和SD卡及其文件系统的初始化
Ø 图片的加载以及显示函数
Ø 主函数
|
|
|
|
|
本帖最后由 lee_st 于 2016-10-13 08:10 编辑
11.2 绘制已经加载到存储器的BMP图片
将图片加载到存储器后进行显示比较的耗内存,所以这里就使用开发板外置的2MB SRAM做STemWin的动态内存空间,并通过相应的API函数申请动态内存来加载SD卡等外部存储器中的BMP图片。申请和释放STemWin动态内存的方法如下:
复制代码
/* 申请一块内存空间 并且将其清零 */
hMem = GUI_ALLOC_AllocZero(100000);
/* 将申请到内存的句柄转换成指针类型 */
_acBuffer2 = GUI_ALLOC_h2p(hMem);
/* 释放申请的动态内存 */
GUI_ALLOC_Free(hMem);
比如我们要显示下面的BMP格式的图片:
就可以把这个图片放到SD卡中,然后通过程序把这个图片数据全部的加载到SRAM中,最后在屏上进行显示。这个工程的实现主要分为如下三个部分:
Ø SRAM和SD卡及其文件系统的初始化
Ø 图片的加载以及显示函数
Ø 主函数
|
|
|
|
|
1. 初始化SRAM,主要是FSMC的配置
2. 初始化文件系统FatFS,用于外接SD卡的读写操作。
l 图片的加载以及显示函数
复制代码
/*
*********************************************************************************************************
* 函 数 名: _ShowBMP
* 功能说明: 显示BMP图片
* 形 参:sFilename 要显示的图片名字
* 返 回 值: 无
*********************************************************************************************************
*/
static void _ShowBMP(const char * sFilename)
{
int XSize, YSize;
GUI_HMEM hMem;
char *_acBuffer2;
int i;
/* 申请一块内存空间 并且将其清零 */
hMem = GUI_ALLOC_AllocZero(1024*1024);(1)
/* 将申请到内存的句柄转换成指针类型 */
_acBuffer2 = GUI_ALLOC_h2p(hMem);
/* 打开文件 */
result = f_open(&file, sFilename, FA_OPEN_EXISTING | FA_READ | FA_OPEN_ALWAYS);(2)
if (result != FR_OK)
{
return;
}
result = f_read(&file, _acBuffer2, file.fsize, &bw);(3)
if (result != FR_OK)
{
return;
}
XSize = GUI_BMP_GetXSize(_acBuffer2);(4)
YSize = GUI_BMP_GetYSize(_acBuffer2);
while(1)
{
for(i = 100; i < 600; i += 10)
{
GUI_BMP_DrawScaled(_acBuffer2, (5)
(LCD_GetXSize() - XSize*i/100)/2,
(LCD_GetYSize() - YSize*i/100)/2,
i,
100);
GUI_Delay(100);
}
GUI_Clear();
}
// GUI_ALLOC_Free(hMem);(6)
// f_close(&file);
}
|
|
|
|
|
1. 申请1MB的动态内存。并将申请到内存的句柄转换为指针类型。
2. 打开相应的BMP文件。
3. 读取BMP文件数据,并将数据全部存储到申请的动态内存里面。
4. 函数GUI_BMP_GetXSize()和GUI_BMP_GetYSize()用于返回BMP图片的大小。
5. 函数GUI_BMP_DrawScaled主要用于实现图片的放缩操作。这里是将图片显示到屏的正中。
6. 释放申请的动态内存,申请的动态内存一定要记得释放。
l 主函数
复制代码
/*
*********************************************************************************************************
* 函 数 名: MainTask
* 功能说明: GUI主函数
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void MainTask(void)
{
GUI_Init();
/* 设置皮肤函数 */ (1)
PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX);
FRAMEWIN_SetDefaultSkin(FRAMEWIN_SKIN_FLEX);
PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX);
BUTTON_SetDefaultSkin(BUTTON_SKIN_FLEX);
CHECKBOX_SetDefaultSkin(CHECKBOX_SKIN_FLEX);
DROPDOWN_SetDefaultSkin(DROPDOWN_SKIN_FLEX);
SCROLLBAR_SetDefaultSkin(SCROLLBAR_SKIN_FLEX);
SLIDER_SetDefaultSkin(SLIDER_SKIN_FLEX);
HEADER_SetDefaultSkin(HEADER_SKIN_FLEX);
RADIO_SetDefaultSkin(RADIO_SKIN_FLEX);
while(1) (2)
{
_ShowBMP("1.bmp");
}
}
|
|
|
|
|
1. 这里是开启皮肤色。
2. 在主程序中调用图片显示即可。
实际显示效果如下:
第一幅是原始图片:
|
|
|
|
|