声明:本文章纯属学习研究,之所以使用这个素材,一是觉着好玩,二是在这个动图中,人物的动作比较大,这样子效果比较好。没有冒犯他人之意。
再者,文章若有侵权请联系本人进行删除。
工具:硬件:STC8A8K64S4A12开发板、128×64 0.96寸OLED
软件:Keil C51、stc-isp-15xx-v6.87C、PictureReader、GIF Movie Gear、Gifsplitter、Dev C++
素材:蔡徐坤打篮球
前言:OLED的一些基础问题,比如如何显示字符、图形这次就先不讲了,否则晚上就得熬夜了。
一、总体思路
在OLED上面播放动图是前几天晚上的突发奇想,到网上搜了一下之后发现没有特别简单方便的方法,最好理解的一个思路就是把gif动图分解成一帧帧的形式,然后分别进行图像取模,将得到的数组存入程序,再利用原有的图像显示程序,就好了。由于新加的程序很简单,所以这次基本上是在介绍几个工具。
二,具体实施
01
调整动图
从网上下载下来的动图有两个问题,一个是分辨率可能不符合128×64(这时用于图像取模的软件PictureReader就会出错,不知道是我自己的问题还是软件本身就是这样);另一个问题是动图包含的帧数太多,这样等下就会crtl+c、crtl+v到手抽筋(同样的,PictureReader有一个批量转换的功能,但是会出错)。于是乎,我们的第一个小工具GIF Movie Gear闪亮登场。
将gif图片打开后,选择“动画”,可以看到,其中有两个我们准备使用的功能:“减少帧数”和“调整大小”。如果有问题的话,可以先点击“取消优化”。
02
动图分解
使用Gifsplitter可以轻松完成这一工作。这个小工具的界面极其简单:
我们只要①将需要分解的gif动图文件路径准备好;②输出路径准备好;③自行确定是否“对透明的Gif采用单色背景”;④最后点击“开始分离”。即可得到心中所要。
03
图像取模
然后便是漫长的取模之路了。开始用上本次起到关键作用的PictureReader。
使用起来也很简单,你可以调整阈值,得到不同效果的图像,也可以取反,也可以选择“字模模式”或者“ASCII”模式(我是选择“字模模式”)。由于无法保存文件,我只好每次复制起来。
04
编程
终于到了编程的环节了。
激动地搓搓手。(我好累,好想睡觉) 还好程序并不复杂。首先我把得到的多幅图像取模后的数组添加到程序中,而后在main.c中加入显示函数。我是这样写的:
int main(void)
{
OLED_Init(); //初始化OLED
OLED_Clear() ;
while(1)
{
OLED_DrawBMP(0,0,128,8,cxk0);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk1);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk2);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk3);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk4);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk5);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk6);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk7);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk8);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk9);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk10);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk11);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk12);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk13);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk14);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk15);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk16);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk17);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk18);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk19);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk20);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk21);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk22);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk23);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk24);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk25);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk26);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk27);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk28);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk29);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk30);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk31);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk32);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk33);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk34);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk35);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk36);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk37);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk38);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk39);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk40);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk41);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk42);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk43);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk44);delay_ms(120);
OLED_DrawBMP(0,0,128,8,cxk45);delay_ms(120);
}
}
其中的“OLED_DrawBMP(0,0,128,8,cxk45)”就是一个封装好的显示图片的函数了,而每一帧要花多少时间(“delay_ms(120); ”)自己定。
原来我是写了一行,然后复制粘贴,再改数值,这样费时费力,最后我想到用 DEV C++写个for循环,工作量大大减少。代码如下:
#include
int main()
{
int i;
for(i = 0;i < 46;i ++)
{
printf("OLED_DrawBMP(0,0,128,8,cxk");
printf("%d",i);
printf(");delay_ms(120); \n");
}
return 0;
}
三、效果展示
由于自己是个学习单片机的小白,所以暂时只能想到这么一个较为简单不过十分费时的方法,欢迎大家指正。
另外,本来做了两幅动图,想加个按键,选择播放,但是两大数组同时放进程序后,编译出错了,我想应该是STC8A8K64S4A12的SRAM只有8k,不够用,不知道我还没学到的flash和外部扩展SRAM能不能救它。