<Rust><iced>在iced中显示gif动态图片的一种方法

前言

本文是在rust的GUI库iced中在窗口显示动态图片GIF格式图片的一种方法。

环境配置

系统:window

平台:visual studio code

语言:rust

库:iced、image

概述

在iced中,提供了image部件,从理论上说,image是支持gif图片的,但是如果你直接将gif的图片路径提供给image,获取图片的handle数据,然后在UI上显示这个image,是无法显示动态图片的,通常,这种情况下,只会显示gif图片的第一帧。

看下面的示例:

上面这张gif图片,如果直接使用下面的显示方式:

rust 复制代码
let imghandle=image::Handle::from_path(&self.imgfile); 
        let img1=image(imghandle).content_fit(iced::ContentFit::Contain);

效果如下:

如上图的左边,image部件只会显示这个gif的第一帧。而右边的图片则是动态的,下面我就来说一下让gif动态显示的方法。

事实上,这个方法是一种间接的方法,iced库的作者提供了一个方法,即使用Subscription来订阅window::frame事件:

rust 复制代码
let sub_f=iced::window::frames().map(Message::Tick);

这个事件会根据当前系统硬件来刷新,它触发的就是窗口的重绘。

它返回的数据是Instant,是iced中的time的时刻数据,即当前的时间片。

所以,我们根据这个实时刷新的机制,就可以来显示动态的图形,包括gif。

具体逻辑是这样的,先使用image库来获取gif图片的底层数据:

rust 复制代码
let gf=std::io::BufReader::new(std::fs::File::open("..\\pidpid\\imgout\\pidpid.gif").unwrap()); 
                let mut g1=eximg::codecs::gif::GifDecoder::new(gf).unwrap();
                let g2=g1.into_frames().collect_frames().expect("msg");

如上,g2是gif图片的数据集合,其类型是Vec< Frame>,Frame即gif的每一帧图片。

我们通过索引来获取g2中的每一帧Frame,然后将Frame转为Vec< u8>格式,即图片转为字节数组格式。

这样一来,我们就可以使用iced中的image部件的from_pixels函数,来通过字节数组显示图片:

rust 复制代码
let imghandle2=image::Handle::from_pixels(200, 200, self.pixpix.clone()); 
        let img2=image(imghandle2).content_fit(iced::ContentFit::Contain);

这样,我们就通过将gif图片分割,然后将每一帧单独显示到image部件,再通过订阅window::frame来修改gif数据组的索引,以此来显示gif的不同帧:

rust 复制代码
  let gf=std::io::BufReader::new(std::fs::File::open("..\\pidpid\\imgout\\pidpid.gif").unwrap());    
                let mut g1=eximg::codecs::gif::GifDecoder::new(gf).unwrap();
                let g2=g1.into_frames().collect_frames().expect("msg");
        
                if self.pixnum >7{
                    self.pixnum=0;
                }
                self.pixpix=g2[self.pixnum].buffer().to_vec();

                self.pixnum +=1;

这就是间接实现iced中显示动态gif图片的一种方法,看下实际演示:

稍后添加

相关推荐
AI源码16 分钟前
基于 Python 的短视频用户行为分析系统
开发语言·python
IT规划师23 分钟前
编程术语中的同步与异步:从"等不等"到工程取舍
后端·面试
旖旎夜光1 小时前
【C++ 基础入门】类和对象(上):封装、对象模型与 this 指针
开发语言·c++·笔记·学习
揽星河..1 小时前
【C语言】结构体
c语言·开发语言
孟陬1 小时前
Foobar 技术周刊#159:当看不懂代码时,如何高效排障调试。脏页陷阱:一条只读查询,写入数 TB 数据。推测解码:大模型加速利器
前端·人工智能·后端
GoGeekBaird1 小时前
别再给每个 AI 做自我介绍了:我做了一个「个人上下文」管理系统
后端·github·agent
2601_966949651 小时前
如何封装 qd.klines.batch(),让批量 K 线查询函数在多个策略中复用?
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
码事漫谈1 小时前
腾讯混元 Hy4 正式版发布了
后端
Mikko71 小时前
Redis 连接数满了服务端有错误信息吗?连接数不增加却命令超时?6.2 实测连接池、超时与大 key 怎么判定
java·spring boot·redis·后端
神仙别闹3 小时前
基于Python实现英词语自动对齐系统
开发语言·python