use fast_image_resize as fr; use fr::{PixelType, ResizeAlg, ResizeOptions, Resizer, images::Image}; use std::io::Cursor; use tokio::fs; #[tokio::main] async fn main() { let start = std::time::Instant::now(); let base_path = "/mnt/c/Users/Formulatrix/Documents/Explorations/WebApplication1/tiles1705/"; const SCALE: f64 = 0.3; const SIZE: u32 = 720; let actual_size = (SIZE as f64 * SCALE).trunc() as u32; // Open the image (a PhotonImage is returned) // let max_col = 30; // let max_row = 30; let max_col = 31; let max_row = 55; let canvas_width = (max_row * actual_size) as usize; let canvas_height = (max_col * actual_size) as usize; let mut canvas = vec![0u8; canvas_width * canvas_height * 3]; let mut resizer = Resizer::new(); for i in 1..=max_col { for j in 1..=max_row { let filename = format!("{}{}{}.png", base_path, number_to_column(i), j); // println!("{filename}"); let data = Cursor::new(fs::read(filename).await.unwrap()); // .unwrap(); let decoder = png::Decoder::new(data); let mut reader = decoder.read_info().unwrap(); let mut buf = vec![0; reader.output_buffer_size()]; let _info = reader.next_frame(&mut buf).unwrap(); let src_img = Image::from_vec_u8(SIZE, SIZE, buf, PixelType::U8x3).unwrap(); let mut img = Image::new(actual_size, actual_size, PixelType::U8x3); resizer .resize( &src_img, &mut img, &ResizeOptions::new() .resize_alg(ResizeAlg::Nearest) .use_alpha(false), ) .unwrap(); place_image( &mut canvas, canvas_width as usize, canvas_height as usize, &img.into_vec(), (actual_size) as usize, (actual_size) as usize, (j * actual_size) as usize, (i * actual_size) as usize, ); } } let file = std::fs::File::create("raw_image.png").unwrap(); let writer = std::io::BufWriter::new(file); let mut encoder = png::Encoder::new( writer, canvas_width.try_into().unwrap(), canvas_height.try_into().unwrap(), ); encoder.set_color(png::ColorType::Rgb); encoder.set_depth(png::BitDepth::Eight); let mut png_writer = encoder.write_header().unwrap(); png_writer.write_image_data(&canvas).unwrap(); let duration = start.elapsed(); println!("Operation completed in: {:.2?}", duration); } fn number_to_column(mut num: u32) -> String { let mut result = String::new(); while num > 0 { num -= 1; let ch = ((num % 26) as u8 + b'A') as char; result.insert(0, ch); num /= 26; } result } fn place_image( canvas: &mut [u8], canvas_width: usize, canvas_height: usize, image: &[u8], image_width: usize, image_height: usize, x_offset: usize, y_offset: usize, ) { let channels = 3; for row in 0..image_height { let canvas_y = y_offset + row; if canvas_y >= canvas_height { continue; } let canvas_start = (canvas_y * canvas_width + x_offset) * channels; let canvas_end = canvas_start + image_width * channels; let image_start = row * image_width * channels; let image_end = image_start + image_width * channels; if canvas_end <= canvas.len() && image_end <= image.len() { canvas[canvas_start..canvas_end].copy_from_slice(&image[image_start..image_end]); } } }