2025-07-03 18:40:44 +07:00
|
|
|
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();
|
2025-07-02 19:44:20 +07:00
|
|
|
let base_path = "/mnt/c/Users/Formulatrix/Documents/Explorations/WebApplication1/tiles1705/";
|
2025-07-03 18:40:44 +07:00
|
|
|
const SCALE: f64 = 0.3;
|
2025-07-02 19:44:20 +07:00
|
|
|
const SIZE: u32 = 720;
|
|
|
|
|
let actual_size = (SIZE as f64 * SCALE).trunc() as u32;
|
|
|
|
|
|
|
|
|
|
// Open the image (a PhotonImage is returned)
|
2025-07-03 18:40:44 +07:00
|
|
|
// let max_col = 30;
|
|
|
|
|
// let max_row = 30;
|
2025-07-02 19:44:20 +07:00
|
|
|
let max_col = 31;
|
|
|
|
|
let max_row = 55;
|
2025-07-03 18:40:44 +07:00
|
|
|
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();
|
2025-07-02 19:44:20 +07:00
|
|
|
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}");
|
|
|
|
|
|
2025-07-03 18:40:44 +07:00
|
|
|
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,
|
2025-07-02 19:44:20 +07:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-07-03 18:40:44 +07:00
|
|
|
let file = std::fs::File::create("raw_image.png").unwrap();
|
|
|
|
|
let writer = std::io::BufWriter::new(file);
|
2025-07-02 19:44:20 +07:00
|
|
|
|
2025-07-03 18:40:44 +07:00
|
|
|
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);
|
2025-07-02 19:44:20 +07:00
|
|
|
}
|
|
|
|
|
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
|
|
|
|
|
}
|
2025-07-03 18:40:44 +07:00
|
|
|
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]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|