本帖最后由 硬汉Eric2013 于 2015-3-26 11:59 编辑
11.3 绘制无需加载到存储器的BMP图片 绘制无需加载到存储器的BMP图片方式可以有效的解决内部动态内存不够的情况,不过缺点也很明显,图片的显示速度很慢。这种方式一般是每次读取一行像素的数据,然后进行显示。这个工程的实现主要分为如下三个部分: Ø 使用芯片内部的SRAM作为动态内存 Ø 图片的加载以及显示函数 Ø 主函数 下面把这三部分详细的讲解下: l 使用芯片内部的SRAM作为动态内存(在文件GUIConf.c里面)
- /*
- *********************************************************************************************************
- *
- * Defines
- *
- ********************************************************************************************************
- */
- /* Define the available number of bytes available for the GUI */
- #define GUI_NUMBYTES (1024*70)(1)
- /* Define the average block size */
- #define GUI_BLOCKSIZE 0x80(2)
- /*********************************************************************
- *
- * GUI_X_Config
- *
- * Purpose:
- * Called during the initialization process in order to set up the
- * available memory for the GUI.
- **********************************************************************
- */
- void GUI_X_Config(void)
- {
- #if 1(3)
- /* 32 bit aligned memory area */
- static U32 aMemory[GUI_NUMBYTES / 4];
- /* Assign memory to emWin */
- GUI_ALLOC_AssignMemory(aMemory, GUI_NUMBYTES);
- GUI_ALLOC_SetAvBlockSize(GUI_BLOCKSIZE);
- #else
- static U32 *aMemory;
- aMemory = (U32 *)EXT_SRAM_ADDR;
- /* Assign memory to emWin */
- GUI_ALLOC_AssignMemory(aMemory, GUI_NUMBYTES);
- GUI_ALLOC_SetAvBlockSize(GUI_BLOCKSIZE);
- #endif
- }
复制代码
1. 定义动态内存的大小,单位是字节。 2. 这里是定义内存块的大小,默认每个内存的大小是128字节。内存块的实际大小要看用户程序的需要,测试那种情况下最省内存,一般情况下取128个字节即可。 3. 这里是使用芯片内部的内存作为STemWin的动态内存空间。 l 图片的加载以及显示函数
- /* 实际的测试需要是图像宽度的4倍即可,切记(也就是保证每个像素如果是32位数据的情况) */
- static char _acBuffer[480*4]; (1)
- /*
- *********************************************************************************************************
- *
- * _GetData
- *
- * Purpose:
- * This routine is called by GUI_JPEG_DrawEx(). The routine is responsible
- * for setting the data pointer to a valid data location with at least
- * one valid byte.
- *
- * Parameters:
- * p - Pointer to application defined data.
- * NumBytesReq - Number of bytes requested.
- * ppData - Pointer to data pointer. This pointer should be set to
- * a valid location.
- * StartOfFile - If this flag is 1, the data pointer should be set to the
- * beginning of the data stream.
- *
- * Return value:
- * Number of data bytes available.
- *********************************************************************************************************
- */
- static int _GetData(void * p, const U8 ** ppData, unsigned NumBytesReq, U32 Off) (2)
- {
- static int FileAddress = 0;
- UINT NumBytesRead;
- FIL *PicFile;
- PicFile = (FIL *)p;
- /*
- * Check buffer size
- */
- if (NumBytesReq > sizeof(_acBuffer)) {
- NumBytesReq = sizeof(_acBuffer);
- }
- /*
- * Set file pointer to the required position
- */
- if(Off == 1) FileAddress = 0;
- else FileAddress = Off;
- result =f_lseek(PicFile, FileAddress);
- /*
- * Read data into buffer
- */
- result = f_read(PicFile, _acBuffer, NumBytesReq, &NumBytesRead);
- /*
- * Set data pointer to the beginning of the buffer
- */
- *ppData = (const U8 *)_acBuffer;
- /*
- * Return number of available bytes
- */
- return NumBytesRead;
- }
- /*
- *********************************************************************************************************
- * 函 数 名: _ShowBMPEx
- * 功能说明: 显示BMP图片
- * 形 参:sFilename 要显示图片的名字
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void _ShowBMPEx(const char * sFilename)
- {
- OS_ERR err;
- /* 打开文件 */
- result = f_open(&file, sFilename, FA_OPEN_EXISTING | FA_READ | FA_OPEN_ALWAYS);
- if (result != FR_OK)
- {
- return;
- }
- // XSize = GUI_BMP_GetXSizeEx(_GetData, &file);
- // YSize = GUI_BMP_GetYSizeEx(_GetData, &file);
- OSSchedLock(&err); (3)
- GUI_BMP_DrawEx(_GetData, &file, 0, 0);(4)
- OSSchedUnlock(&err);
- f_close(&file);
- }
复制代码
1. 这个数据空间的大小比较讲究,至少得保证大于等于实际要显示图片一行像素的数据。比如要显示800*480分辨率,16bpp的一幅图片,那这个buffer的大小至少得是800*(16/8) = 1600字节。 2. 这个函数非常重要,大家要认真看一下英文注释即可。 3. 加上调度锁,防止图片显示的过程中出现异常。 4. 实现图片的显示函数。 l 主函数
- /*
- *********************************************************************************************************
- * 函 数 名: MainTask
- * 功能说明: GUI主函数
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void MainTask(void)
- {
- GUI_Init();
- /* 设置皮肤函数 */
- 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);
- _ShowBMPEx("1.bmp");
- while(1)
- {
- GUI_Delay(200);
- }
- }
复制代码
实际显示效果如下: |