18.3.2 绘制无需加载到存储器的GIF图片
绘制无需加载到存储器的GIF图片主要是通过函数GUI_GIF_DrawSubEx来实现,这种方式的优点是需要的内存小,但是显示速度稍慢。下面我们分2步来说明如何将SD卡中的GIF图片显示到LCD上面。
第1步:将GIF图片复制到SD卡的根目录下,然后直接调用函数GUI_GIF_DrawSubEx就可以显示。
复制代码
/*
*********************************************************************************************************
* 函 数 名: _GetData
* 功能说明: 被函数GUI_BMP_DrawEx调用
* 形 参:p FIL类型数据
* NumBytesReq 请求读取的字节数
* ppData 数据指针
* Off 如果Off = 1,那么将重新从起始位置读取
* 返 回 值: 返回读取的字节数
*********************************************************************************************************
*/
int _GetData(void * p, const U8 ** ppData, unsigned NumBytesReq, U32 Off)
{
static int FileAddress = 0;
UINT NumBytesRead;
FIL *PicFile;
PicFile = (FIL *)p;
/*
* 检测缓存大小
*/
if (NumBytesReq > sizeof(acBuffer)) {
NumBytesReq = sizeof(acBuffer);
}
/*
* 设置读取位置
*/
if(Off == 1) FileAddress = 0;
else FileAddress = Off;
result =f_lseek(PicFile, FileAddress);
/*
* 读取数据到缓存
*/
result = f_read(PicFile, acBuffer, NumBytesReq, &NumBytesRead);
/*
* 让指针ppData指向读取的数据
*/
*ppData = (const U8 *)acBuffer;
/*
* 返回读取的字节数
*/
return NumBytesRead;
}
/*
*********************************************************************************************************
* 函 数 名: _ShowGIF1
* 功能说明: 显示GIF片
* 形 参: sFilename 要显示的图片名字
* 返 回 值: 无
*********************************************************************************************************
*/
void _ShowGIF1(const char * sFilename)
{
uint16_t i = 0;
uint32_t t0, t1;
char buf[50];
/* 打开文件 */
result = f_open(&file, sFilename, FA_OPEN_EXISTING | FA_READ | FA_OPEN_ALWAYS);
if (result != FR_OK)
{
return;
}
/* 获取GIF图片信息 */
GUI_GIF_GetInfoEx(_GetData, &file,&InfoGif);
while(1)
{
/* 变量用来设置当前播放的帧数,InfoGif.NumImages是GIF图片总的帧数 */
if(i < InfoGif.NumImages)
{
/* 获取当前帧GIF图片信息,注意第4个参数是从0开始计数的 */
GUI_GIF_GetImageInfoEx(_GetData, &file, &ImagInfoGif, i);
/* 如果此帧延迟时间是0,默认是延迟100ms */
if(ImagInfoGif.Delay == 0)
{
GUI_Delay(100);
}
else
{
t0 = GUI_GetTime();
/* 显示当前播放的帧数 */
sprintf(buf, " Frame:%d/%d ", i+1, InfoGif.NumImages);
GUI_DispStringHCenterAt(buf, LCD_GetXSize()/2, 0);
/* 解码并显示此帧GIF图片,注意第5个参数是从0开始计数的 */
GUI_GIF_DrawSubEx(_GetData,
&file,
(LCD_GetXSize() - InfoGif.xSize)/2,
(LCD_GetYSize() - InfoGif.ySize)/2,
i++);
/* 获取本次解码和显示消耗的时间 */
t1 = GUI_GetTime() - t0;
/* 如果GIF的解码和显示的时间超时就不做延迟 */
if (t1 < ImagInfoGif.Delay * 10)
{
GUI_Delay(ImagInfoGif.Delay * 10 - t1);
}
}
}
else
{
i = 0;
}
}
/* 实际应用中,根据实际情况释放动态内存 */
// GUI_ALLOC_Free(hMem);
// f_close(&file);
} |