-
-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathski.rs
87 lines (84 loc) · 2.17 KB
/
ski.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
use crate::app::AppResult;
use crate::gif::encoder::{Encoder, EncoderConfig};
use crate::image::Image;
use crate::util::state::InputState;
use gifski::{Collector, Repeat, Writer};
use std::io::{self, Write};
use std::thread;
/* GIF encoder and settings */
pub struct GifskiEncoder<Output: Write> {
fps: u32,
collector: Collector,
writer: Writer,
output: Output,
}
impl<'a, Output: Write> Encoder<'a, Output> for GifskiEncoder<Output> {
/**
* Create a new GifskiEncoder object.
*
* @param config
* @return GifskiEncoder (Result)
*/
fn new(config: EncoderConfig<'a, Output>) -> AppResult<Self> {
let (collector, writer) = gifski::new(gifski::Settings {
width: Some(config.geometry.width),
height: Some(config.geometry.height),
quality: config.settings.quality,
fast: config.settings.gifski.1,
repeat: match config.settings.repeat {
n if n >= 0 => Repeat::Finite(n.try_into().unwrap_or_default()),
_ => Repeat::Infinite,
},
})?;
Ok(Self {
fps: config.fps,
collector,
writer,
output: config.output,
})
}
/**
* Encode images as frame and write to the GIF file.
*
* @param images
* @param input_state (Option)
* @param Result
*/
fn save(
self,
images: Vec<Image>,
input_state: Option<&'static InputState>,
) -> AppResult<()> {
let fps = self.fps;
let collector_thread = thread::spawn(move || {
for (i, image) in images.iter().enumerate() {
let percentage = ((i + 1) as f64 / images.len() as f64) * 100.;
info!("Saving... ({:.1}%)\r", percentage);
debug!(
"Encoding... ({:.1}%) [{}/{}]\r",
percentage,
i + 1,
images.len()
);
io::stdout().flush().expect("Failed to flush stdout");
if let Some(state) = input_state {
if state.check_cancel_keys() {
info!("\n");
warn!("User interrupt detected.");
panic!("Failed to write the frames")
}
}
self.collector
.add_frame_rgba(i, image.get_img_vec(), i as f64 / fps as f64)
.expect("Failed to collect a frame");
}
info!("\n");
});
self.writer
.write(self.output, &mut gifski::progress::NoProgress {})?;
collector_thread
.join()
.expect("Failed to collect the frames");
Ok(())
}
}