gif_encoder.rs - icy_draw - icy_draw is the successor to mystic draw. fork / mirror
HTML git clone https://git.drkhsh.at/icy_draw.git
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
gif_encoder.rs (1561B)
---
1 use std::{path::Path, sync::mpsc::Sender};
2
3 use gifski::{progress::NoProgress, Repeat};
4 use imgref::ImgVec;
5 use rgb::RGBA8;
6
7 use crate::TerminalResult;
8
9 use super::encoding::AnimationEncoder;
10
11 pub struct GifEncoder {}
12
13 impl AnimationEncoder for GifEncoder {
14 fn label(&self) -> String {
15 "GIF".to_string()
16 }
17 fn extension(&self) -> String {
18 "gif".to_string()
19 }
20
21 fn encode(&self, path: &Path, frames: Vec<(Vec<u8>, u32)>, width: usize, height: usize, sender: Sender<usize>) -> TerminalResult<()> {
22 let settings = gifski::Settings {
23 width: Some(width as u32),
24 height: Some(height as u32),
25 quality: 100,
26 fast: true,
27 repeat: Repeat::Infinite,
28 };
29
30 let (c, w) = gifski::new(settings)?;
31 let mut time = 0.0;
32 let mut pb = NoProgress {};
33 let path = path.to_path_buf();
34 let fs = std::fs::File::create(path)?;
35 std::thread::spawn(move || w.write(fs, &mut pb).unwrap());
36
37 for (frame_idx, (data, duration)) in frames.into_iter().enumerate() {
38 sender.send(frame_idx)?;
39 let mut n = 0;
40 let mut d = Vec::new();
41 while n < data.len() {
42 d.push(rgb::RGBA::new(data[n], data[n + 1], data[n + 2], data[n + 3]));
43 n += 4;
44 }
45
46 let img: ImgVec<RGBA8> = imgref::Img::new(d, width, height);
47 c.add_frame_rgba(frame_idx, img, time / 1000.0)?;
48 time += duration as f64;
49 }
50
51 Ok(())
52 }
53 }