开发板:潘多拉开发板
  系统版本:v4.0.3
  

一、将视频转换成图片

  gif 和视频转换的方法都是一样的,这是我选择使用的是太空人的 gif。
  转换的方法就是通过 python + opencv 从视频或 gif 中按帧提取图片,然后保存图片。

  参考代码如下。

import os
import cv2class Picture(object):def __init__(self, video_path, pictures_path):self.video_path = video_pathself.pictures_path = os.path.normpath( os.getcwd() + pictures_path )def find_video(self):if os.path.isfile(self.video_path) == False:print("voide %s dont find." % self.video_path)return Falseself.picture_name = self.video_path.split('/')[-1]  # 设置图片的名称self.picture_name = self.picture_name.split('.')[0]def open_video(self):self.vc = cv2.VideoCapture(self.video_path)     # 读入视频文件self.cnt = 0                                    # 统计对应帧号ret = self.vc.isOpened()                        # 判断视频是否打开if ret == False:print("voide %s open failed." % self.video_path)return retdef get_video_info(self):self.width = self.vc.get(3)         # 视频宽度self.heigth = self.vc.get(4)        # 视频高度self.frame_num = self.vc.get(7)     # 获取视频总帧数print("width:%d  height:%d  frame:%d." % (self.width, self.heigth, self.frame_num))def close_video(self):self.vc.release()def set_picture_param(self, width, heigth):if (width != 0 and heigth != 0):self.frame = cv2.resize(self.frame, (width, heigth))    # 重新设置帧的宽度和高度,也就是图片的宽度和高度def save_picture(self):cnt = 0while True:if os.path.isdir(self.pictures_path) == True:      # 如果当前文件夹存在,则重新创建文件夹cnt += 1if self.pictures_path[-2] == "_":self.pictures_path = self.pictures_path[:-1] + str(cnt)else:self.pictures_path = os.path.normpath( self.pictures_path + "_" + str(cnt) )continueelse:os.mkdir(self.pictures_path)breakret = Truewhile ret:ret, self.frame = self.vc.read()      # 第一个返回值为是否成功获取视频帧,第二个返回值为返回的视频帧if ret:self.set_picture_param(240, 240)cv2.imwrite(self.pictures_path + '/' + self.picture_name + '_' + str(self.cnt) + '.bmp', self.frame) # 存储为图像,名字为:视频名_数字.jpgself.cnt += 1print("save picture done: " + self.pictures_path)def run(self):if self.find_video() == False:returnif self.open_video() == False:returnself.get_video_info()self.save_picture()self.close_video()if __name__ == "__main__":  pic = Picture("./taikonaut.gif", "/pictures")pic.run()

  

二、将图片转换成二进制数据

  由于硬件性能较弱,图片在 STM32 上转码会拖慢处理速度,因此可以选择直接将图片转成二进制数据,让板子读到数据就能直接发送给屏幕。
  这里选择使用 Image2Lcd v3.2 工具。
  格式选择 .bin,水平扫描,16位真彩色(板载屏幕需要的格式)。选择其中一张图片,选择批量转换即可。

  转换完成得到很多张 .bin 格式的图像数据,为了方便,因此可以通过 python 其合并为一个文件。
  参考代码如下。

class Bin(object):def __init__(self, name):self.name = namedef open(self):self.out = open(self.name, "wb")def close(self):self.out.close()def merge(self):for i in range(48):     # 0 - 47,具体根据 bin 文件数量来确定cnt = ifile_name = "./bin/taikonaut_" + str(cnt) + ".bin"if os.path.exists(file_name):self.out.write( open(file_name, "rb").read() )else:print( file_name + " open fail.")def run(self):self.open()self.merge()self.close()if __name__ == "__main__":  bin = Bin("taikonaut.bin")bin.run()

  

三、将图片转换成二进制数据

  RT-Thread 需要开启 LCD、SD 卡、DFS、SPI Flash 功能。
  大概思路如下:
  1)SD 上存放前面得到的 taikonaut.bin 文件。
  2)将 elm FAT 的根目录 / 挂载的 SPI Flash 的 filesystem 分区。
  3)将 SD 卡挂载到 /mnt 目录。
  4)读取 /mnt/taikonaut.bin 内容,并将其显示到 LCD 上。
  
  参考代码如下。

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>#include <fal.h>
#include <dfs_fs.h>
#include <dfs_posix.h>#include <drv_lcd.h>/* defined the LED0 pin: PE7 */
#define LED0_PIN    GET_PIN(E, 7)/*** 因为 RAM 空间大小受限,所以将一帧 240 * 240 按高度分成 10 等分,也就是 240 * 24* 因为是 16 位真彩色,所以要 * 2* 如果 RAM 空间足够,则可以直线分配一帧的空间,不用像这样 10 等分 **/
#define BUFF_LEN (240 * 24 * 2)static rt_thread_t led_tid = RT_NULL;
static rt_thread_t video_tid = RT_NULL;static void led_thread_entry(void *parameter)
{rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);while (1){rt_pin_write(LED0_PIN, PIN_HIGH);rt_thread_mdelay(500);rt_pin_write(LED0_PIN, PIN_LOW);rt_thread_mdelay(500);}
}static void video_thread_entry(void *parameter)
{int fd = -1;int offset = 0;int height = 0;    /* 记录当前高度 */rt_uint8_t *buf = RT_NULL;struct stat stat_buf;if( stat("/mnt/taikonaut.bin", &stat_buf) != -1 ){rt_kprintf("file size : %d.\n", stat_buf.st_size);}fd = open("/mnt/taikonaut.bin", O_RDONLY);if(fd == -1)return;buf = rt_malloc(BUFF_LEN);if( buf == RT_NULL ){rt_kprintf("malloc failed.\n");goto error;}while (1){lseek(fd, offset, 0);read(fd, buf, BUFF_LEN);/* x:0,y:height,width:240,height:24 */lcd_show_image(0, height, 240, 24, buf);offset += BUFF_LEN;height += 24;if(height == 240)height = 0;if( offset == stat_buf.st_size)break;}rt_free(buf);
error:close(fd);rt_kprintf("vidoe thread exit.\n"); return;
}int thread_sample(void)
{led_tid = rt_thread_create("led",led_thread_entry, RT_NULL,256,     /* stack size */25,      /* priority */5);      /* time slice */if (led_tid != RT_NULL)rt_thread_startup(led_tid);video_tid = rt_thread_create("video",video_thread_entry, RT_NULL,2048,     /* stack size */20,       /* priority */5);       /* time slice */if (video_tid != RT_NULL)rt_thread_startup(video_tid);return 0;
}void fs_init(void)
{fal_init();fal_blk_device_create("filesystem");if (dfs_mount("filesystem", "/", "elm", 0, 0) != 0){if(dfs_mkfs("elm", "filesystem") == 0){if (dfs_mount("filesystem", "/", "elm", 0, 0) != 0){rt_kprintf("file system initialization failed!\n");}}}if (opendir("/mnt") == RT_NULL){if (mkdir("mnt", 0x777) == -1)return;}    if(rt_device_find("sd0") == RT_NULL){rt_kprintf("failed to find sd card device.\n");return;}if (dfs_mount("sd0", "/mnt", "elm", 0, 0) != RT_EOK){rt_kprintf("sd card mount to '/mnt' failed!\n");}
}int main(void)
{fs_init();  thread_sample();    return RT_EOK;
}

  

五、效果

【RTT】小项目:显示太空人动画相关推荐

  1. Android小项目之五 splash动画效果

    ------- 源自梦想.永远是你IT事业的好友.只是勇敢地说出我学到! ---------- 按惯例,写在前面的:可能在学习Android的过程中,大家会和我一样,学习过大量的基础知识,很多的知识点 ...

  2. UI小项目之拳皇动画的实现(抽取加载图片和播放音乐的方法)

    实现思路 1.加载图片 2.播放音乐 实现思想 1.封装思想 抽取相同代码生成一个新的方法,通过传递参数调用该方法: 2.内存管理思想 不需要每次调用方法时都重新加载图片,for循环加载图片写在Vie ...

  3. stm32 基于TouchGFX显示视频动画的详细制作过程和讲解

    stm32 使用TouchGFX显示太空人动画详细制作过程 文章目录 1.素材处理 2.Touchgfx移植 3.使用控件animated image 4.仿真和烧录看效果 5.增加启动和暂停控制 1 ...

  4. nginx lua 小项目:根据 user_agent 显示不同的页面,附带和 php 性能的对比

    怎么快速学习一门新的语言呢? 如果你已经熟练掌握了一门语言,那么其他语言都是想通的.一个小小的需求,可能会遇到很多问题,但是搜索相关的关键字,就能快速实现出来,完成一个小目标,事半功倍. 死记硬背手册 ...

  5. PhP加载时显示动画,在微信小程序中如何使用loading组件显示载入动画

    这篇文章主要介绍了微信小程序loading组件显示载入动画用法,结合实例形式分析了loading组件显示载入动画的相关事件操作与属性设置技巧,并附带源码供读者下载参考,需要的朋友可以参考下 本文实例讲 ...

  6. Android实现小圆点显示未读功能

    代码地址如下: http://www.demodashi.com/demo/13541.html ####前言 以前我们实现这个功能都是用 BadgeView.java,大体就是将这个java类复制到 ...

  7. PMEdit一个富文本框可以编辑文本、并可以显示GIF动画

    PMEdit一个富文本框可以编辑文本.并可以显示GIF动画 发布时间:2013-04-14 发布来源: 护士必必要有同情心和一双愿意工作的手. 一.在开端之前起首吐槽一下,本人是一个自力开辟者,在中国 ...

  8. android 小白点代码,Android实现小圆点显示未读功能

    ####前言 以前我们实现这个功能都是用 BadgeView.java,大体就是将这个java类复制到自己的项目中,然后在项目中使用,今天讲的也是一款BadgeView,我将其封装称工具类Badget ...

  9. android计算器开源小项目代码(附安装包.apk)

    最近在学习安卓开发,做了个小计算器作为实践.发现网上的计算器教程代码的健壮性不够好,只能够容忍正确的输入.于是我花了几天时间写了个完整的程序.可能是我水平有限,其中条件控制逻辑设计的比较复杂,但我受开 ...

最新文章

  1. shp系列(六)——利用C++进行Dbf文件的写(创建)
  2. 每日一题:leetcode80.删除有序数组中的重复元素贰
  3. Spring Data JPA框架
  4. log4net 使用手记
  5. python3--迭代器
  6. 关于esp32的省电模式的WiFi连接
  7. 城市交通_ssl1636_floyd
  8. linux系统中rsync的安装和使用,以及配置rsync开机启动
  9. 第四章 MyBatis-SQL映射文件
  10. TakeColor取色器的使用
  11. 如何用两个栈实现一个队列
  12. autojs开发的ip地址查询工具开源代码免费分享
  13. el-upload限制文件大小(图片尺寸)
  14. 五、APP分类和手机选择
  15. mac虚拟机不能识别 iphone或u盘
  16. 机器人教育在高科技领域的主观作用
  17. 博客摘录「 MACD金叉不绿选股公式」2023年5月28日
  18. OBS Studio导播台多画面使用实测
  19. 论文阅读(9)---基于Transformer的多模态CNN心电图心律失常分类
  20. 概率密度函数,参数估计,非参数估计

热门文章

  1. DS-6602HF配置主码流和子码流访问
  2. 如何选择适合自己的培训机构
  3. 小白测试系列:badboy默认浏览器修改
  4. mysql varchar存储字符数
  5. c语言符号函数怎么表示,C语言中的数学符号怎么表示?
  6. Oracle 排序问题
  7. C语言的static函数
  8. 首个女性向3A手游要来了?获IGN认可,《以闪亮之名》能否突出重围
  9. 人工智能Java SDK:图像文本的跨模态相似性比对检索【支持40种语言】
  10. ipv6单播地址包括哪两种类型_【思唯网络学院】CCNP知识点总结——IPv6