pub(crate) mod conversion;
pub mod error;
pub mod fonts;
pub mod image_types;
pub mod options;
use std::{fs::File, io::BufWriter};
use image::{Frame, codecs::gif::GifEncoder};
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use crate::{
conversion::{
converters::{
gif_converter::read_as_deconstructed_rendered_gif_vec,
png_converter::parse_ascii_to_2d_png_vec,
},
image_writer::AsciiImageWriter,
},
error::ImgiiError,
options::ImgiiOptions,
};
pub fn convert_to_ascii_png(
input_file_name: &str,
output_file_name: &str,
imgii_options: &ImgiiOptions,
) -> Result<(), ImgiiError> {
let lines = parse_ascii_to_2d_png_vec(input_file_name, imgii_options)?;
let final_image_writer = AsciiImageWriter::from_2d_vec(lines)?;
final_image_writer
.imagebuf
.as_buffer()
.save(&output_file_name)
.map_err(|err| -> ImgiiError { anyhow::Error::new(err).into() })?;
Ok(())
}
pub fn convert_to_ascii_gif(
input_file_name: &str,
output_file_name: &str,
imgii_options: &ImgiiOptions,
) -> Result<(), ImgiiError> {
let raw_frames = read_as_deconstructed_rendered_gif_vec(input_file_name, imgii_options)?;
let image_writers = raw_frames
.into_par_iter()
.filter_map(|frame_part| frame_part)
.map(|frame_part| {
let (image_data, frame_metadata) = frame_part.into_frame_data();
(AsciiImageWriter::from_2d_vec(image_data), frame_metadata)
})
.collect::<Vec<_>>();
let frames: Vec<Frame> = image_writers
.into_par_iter()
.filter_map(|(writer, frame_metadata)| match writer {
Ok(writer) => Some((writer, frame_metadata)),
Err(_) => None,
})
.map(|(image_writer, frame_metadata)| {
Frame::from_parts(
image_writer.imagebuf.into(), frame_metadata.left(),
frame_metadata.top(),
frame_metadata.delay(),
)
})
.collect();
let out_file = File::create(output_file_name)?;
let file_writer = BufWriter::new(out_file);
let mut gif_encoder = GifEncoder::new(file_writer);
let err = gif_encoder.set_repeat(image::codecs::gif::Repeat::Infinite);
if let Err(err) = err {
let err = anyhow::Error::new(err);
return Err(err.into());
}
match gif_encoder.encode_frames(frames) {
Err(err) => {
let err = anyhow::Error::new(err);
Err(err.into())
}
_ => Ok(()),
}
}