1use image::imageops::FilterType;
2use image::{DynamicImage, GenericImageView, ImageResult, Pixel};
3
4const PIXEL_CHAR_ARRAY: [char; 10] = ['W', '@', '#', '8', '&', '*', 'o', ':', '.', ' '];
5
6pub fn load_image(img_path: &str, target_width: u32) -> ImageResult<DynamicImage> {
8 let img = image::open(img_path)?;
9 Ok(resize_image(img, target_width))
10}
11
12pub fn resize_image(img: DynamicImage, target_width: u32) -> DynamicImage {
13 let (src_width, src_height) = img.dimensions();
14 let target_height = get_target_height(src_width, src_height, target_width);
15 img.resize(target_width, target_height, FilterType::CatmullRom)
16}
17
18pub fn print_image(img: DynamicImage) {
19 let (width, height) = img.dimensions();
20 for i in 0..height {
21 for j in 0..width {
22 let rgb = img.get_pixel(j, i);
23 let rgb = rgb.channels();
24 let (red, green, blue) = (rgb[0], rgb[1], rgb[2]);
25 print!("{}", PIXEL_CHAR_ARRAY[calculate_index(red, green, blue)]);
26 }
27 println!();
28 }
29}
30
31#[inline]
32fn calculate_index(r: u8, g: u8, b: u8) -> usize {
33 let grayscale = 0.2126 * r as f64 + 0.7152 * g as f64 + 0.0722 * b as f64;
34 let index = grayscale / ((255 / PIXEL_CHAR_ARRAY.len()) as f64 + 0.5);
35 index.floor() as usize
36}
37
38#[inline]
40fn get_target_height(src_width: u32, src_height: u32, target_width: u32) -> u32 {
41 let mut target_height = src_height;
42 if target_width < src_width {
43 target_height =
45 (target_height as f64 / (src_width as f64 / target_width as f64)).round() as u32;
46 }
47 target_height
48}