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); } |