加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

【STemWin教程入门篇】第14章 PNG图片显示

(2015-01-14 16:50:41)
标签:

ucos-iii

ucgui

emwin

dsp

png

分类: emWin

特别说明:完整STemWin的1-60期教程和配套实例下载地址:链接

第14章       PNG图片显示

本期主要讲STemWin支持的PNG图片的显示,官方支持的主要有两种显示方法,一种是从外部存储器读取数据到内部存储器,然后来显示图片,这种的显示速度要快些,另一种方法是直接从外部存储器读取数据并显示,这种办法的好处就是不要大的RAM需求,每次读取一些数据显示一次,坏处就是显示速度比较的慢。

这里将2MB的外部SRAM做为emWin的动态内存,PNG的图片显示相当耗费RAM

有一点在这里提前得和大家说明,对于PNG的库,STemWin里面是不带的,需要自己添加,从SEGGER的官网下载,这个库是来自libpng,官网www.libpng.org

14 1  PNG图片支持

14. 2 绘制已经加载到存储器的PNG图片

14. 3 绘制无须加载到存储器的PNG图片

14. 4 实验总结

14.1  PNG图片支持

PNG(可移植的网络图形)格式是一种图像格式,它利用非专利的数据压缩方法提供无损的数据压缩Alpha混合。PNG 1.0版规范于1996年发布。到2003年末,PNG成为国际标准(ISO/IEC15948)

emWinPNG支持的实施基于来自Glenn Randers-PehrsonGuy Eric SchalnatAndreas Dilger的“libpng”库,该库可在www.libpng.org下免费获得。emWin对该库的使用符合GUI\PNG\png.h中的版权通知,通知中允许使用该库,而没有任何限制。

图形库首先对图形信息进行解码。如果必须绘制图像,解码流程将花费相当长的时间。如果在窗口管理器经常调用的callback例程中使用PNG文件,则解码流程可能花费相当长的时间。通过使用存储设备可缩短计算时间。最好的方法是先将图像绘制到存储设备中。在这种情况下,将只进行一次解压缩。

SEGGER官网下载的png如下,这里我们使用最新的5.18版本:

【STemWin教程入门篇】第14章 <wbr>PNG图片显示

 

14.1.1       PNG格式图标转换

某些情况下,将PNG文件作为C文件添加到项目中非常有用。对此,可完全按照前面介绍的“JPEG文件支持”下的相同方式来执行。此外,位图转换器能够加载PNG文件并将它们转换为C位图文件。下面举一个例子,跟大家演示下:比如我们要转换如下的PNG图标:

【STemWin教程入门篇】第14章 <wbr>PNG图片显示

 

l  打开软件加载上面的图片

【STemWin教程入门篇】第14章 <wbr>PNG图片显示

 

l  加载后点击Convert即可,点击后没有任何现象,直接去图片所在的文件夹找即可

【STemWin教程入门篇】第14章 <wbr>PNG图片显示

 

实际运行代码如下(图片数据就不贴出来了,看本期教程配套的例子

void MainTask(void)

  

    GUI_Init();

     GUI_PNG_Draw(_acmusic, sizeof(_acmusic), 20, 20);

    while(1)

    {

        GUI_Delay(100);

    }

}

由于在Bin2C的小工具是来自MDK安装目录中,这个工具只是评估板,无法实现PNG图标的透明色效果。模拟器实际的显示效果如下:

【STemWin教程入门篇】第14章 <wbr>PNG图片显示

 

14.1.2       PNG存储器方式显示

为了区分上面将图片转换为C文件进行显示,这里将PNG图片存入到外部SD卡等存储器中进行加载显示。

首先要注意PNG需要的动态内存大小。PNG解压缩大约需要21 Kb RAM用于与图像大小无关的解压缩和依赖大小的字节量。RAM要求可按以下方式计算:

大约RAM要求= (X-Size + 1)* Y大小* 4 + 21Kbytes

当前STemWin支持的PNG图片 API函数如下:

【STemWin教程入门篇】第14章 <wbr>PNG图片显示

 

14.2  绘制已经加载到存储器的PNG图片

将图片加载到存储器后进行显示比较的耗内存,所以这里就使用开发板外置的2MB SRAMSTemWin的动态内存空间,并通过相应的API函数申请动态内存来加载SD卡等外部存储器中的PNG图片。申请和释放STemWin动态内存的方法如下:

 

hMem = GUI_ALLOC_AllocZero(100000);

 

_acBuffer2 = GUI_ALLOC_h2p(hMem);

 

GUI_ALLOC_Free(hMem);

这里还用上面的图片作为显示对象。先把这个图片放到SD卡中,然后通过程序把这个图片数据全部的加载到SRAM中,最后在屏上进行显示。这个工程的实现主要分为如下三个部分:

Ø  SRAMSD卡及其文件系统的初始化

Ø  图片的加载以及显示函数

Ø  主函数

下面把这三部分详细的讲解下:

l  SRAMSD卡及其文件系统的初始化,这部分函数与上面第11章的11.2小节一样。

l  图片的加载以及显示函数

 

static void _ShowPNG(const char * sFilename, uint16_t usPOSX, uint16_t usPOSY)

{

     GUI_HMEM hMem;

     char *_acBuffer2;

 

    

    hMem = GUI_ALLOC_AllocZero(500000);

    

     _acBuffer2 = GUI_ALLOC_h2p(hMem);

 

    

             

     result = f_open(&file, sFilename, FA_OPEN_EXISTING | FA_READ | FA_OPEN_ALWAYS);

     if (result != FR_OK)

     {

         return;

     }

 

     result = f_read(&file, _acBuffer2, file.fsize, &bw);

     if (result != FR_OK)

     {

         return;

     }

 

     GUI_PNG_Draw(_acBuffer2, file.fsize, usPOSX, usPOSY);

     GUI_ALLOC_Free(hMem);

     f_close(&file);

}

l  主函数

 

void MainTask(void)

  

     GUI_Init();

     GUI_SetBkColor(GUI_BLUE);

     GUI_Clear();

    

   

     _ShowPNG("1.png", 0, 0);

     _ShowPNG("2.png", 100, 0);

    

     while(1)

                    

         GUI_Delay(100);

     }

 

}

实际显示效果如下:

【STemWin教程入门篇】第14章 <wbr>PNG图片显示

 

编译,链接工程的时候会出现大量如下的警告:

【STemWin教程入门篇】第14章 <wbr>PNG图片显示

 

这个是由于使用的PNG库和现在STemWin5.22版本不匹配造成的,PNG的库是用5.18版本的,最新的5.22版本官方还没有更新。

14.3  绘制无需加载到存储器的PNG图片

绘制无需加载到存储器的PNG图片方式可以有效的解决内部动态内存不够的情况,不过缺点也很明显,图片的显示速度很慢。这种方式一般是每次读取一行像素的数据,然后进行显示。这个工程的实现主要分为如下三个部分:

Ø  使用芯片内部的SRAM作为动态内存

Ø  图片的加载以及显示函数

Ø  主函数

下面把这三部分详细的讲解下:

l  使用芯片外部的SRAM作为动态内存,这部分函数与上面第11章的11.2小节一样,由于PNG比较的消耗内存,这里和BMP不同也需要使用动态内存。

l  图片的加以及显示函数。

 

 

static int _GetData(void * p, const U8 ** ppData, unsigned NumBytesReq, U32 Off) {

     static int FileAddress = 0;

     FIL *file;

     DWORD    NumBytesRead;

     U8     * pData;

 

     pData  = (U8 *)*ppData;

     file = (FIL *)p;

     //

     // Set file pointer to the required position

     //

     if(Off == 1) FileAddress = 0;

     else FileAddress = Off;

     result =f_lseek(file, FileAddress);

     //

     // Read data into buffer

     //

     result = f_read(file, pData, NumBytesReq, &NumBytesRead);

 

     //

     // Return number of available bytes

     //

     return NumBytesRead;

 

}

 

static void _ShowPNGEx(const char * sFilename, uint16_t usPOSX, uint16_t usPOSY)

  

 

             

     result = f_open(&file, sFilename, FA_OPEN_EXISTING | FA_READ | FA_OPEN_ALWAYS);

     if (result != FR_OK)

     {

         return;

     }

    

     GUI_PNG_DrawEx(_GetData, &file, usPOSX, usPOSY);

 

     f_close(&file);

}

l  主函数

 

void MainTask(void)

  

     GUI_Init();

     GUI_SetBkColor(GUI_BLUE);

     GUI_Clear();

    

    

     _ShowPNGEx("3.png", 0, 100);

     _ShowPNGEx("4.png", 100,100);

    

     while(1)

                    

         GUI_Delay(100);

     }

 

}

实际显示效果如下:

【STemWin教程入门篇】第14章 <wbr>PNG图片显示

 

14.4  实验总结

有兴趣的可以了解一下PNG压缩方面的知识。如果只是API应用的话,这部分知识还是比较容易学会的。PNG图标用到的地方还是比较多的。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有