use image::bmp::BMPEncoder; use image::ColorType; use rayon::prelude::*; use std::env; use std::fs::File; use std::io::{self, BufWriter}; use std::path::Path; fn main() -> Result<(), io::Error> { let args = env::args().skip(1).collect::>(); if args.len() != 2 { return Err(io::Error::new( io::ErrorKind::InvalidInput, format!("Expected 2 arguments: "), )); } let input_path = Path::new(&args[0]); let mut output_path = Path::new(&args[1]).to_path_buf(); let mut file = File::open(&input_path)?; match giffy::load(&mut file) { Ok(gif) => { println!("Frame count: {}", gif.image_frames.len()); let mut tasks = vec![]; let mut counter = 1; for frame in gif.image_frames { let file_name = format!( "{}-frame-{}.bmp", input_path.file_name().unwrap().to_str().unwrap(), counter ); output_path.push(&file_name); tasks.push((counter, frame, output_path.clone())); output_path.pop(); counter += 1; } let width = gif.width; let height = gif.height; tasks.par_iter().for_each(|e| { let (counter, frame, path) = e; let mut writer = BufWriter::new(File::create(&path).expect("File not found")); let mut encoder = BMPEncoder::new(&mut writer); println!( "Writing frame #{} to '{}'", counter, path.file_name().unwrap().to_str().unwrap() ); let mut colors = vec![]; for c in frame.colors.iter() { let values: [u8; 3] = c.into(); colors.extend(&values); } encoder .encode(&colors, width, height, ColorType::RGB(8)) .expect("Error encoding"); }); } Err(e) => println!("{}", e), } Ok(()) }