use anyhow::Context;
use image::{self, DynamicImage, GenericImageView, Rgb};
use crate::consts::Version;
pub fn get_target_scale(path: String, side_len: usize) -> anyhow::Result<Vec<Vec<(u32, u8)>>> {
let target = image::open(path).context("Could not open target image")?;
let scaled = target.resize_exact(
side_len as u32,
side_len as u32,
image::imageops::FilterType::Gaussian,
);
let brightness = make_brightness_array(scaled);
let mut result = Vec::with_capacity(side_len);
for y in 0..side_len {
let mut row = Vec::with_capacity(side_len);
for x in 0..side_len {
row.push((
get_contrast(x as u32, y as u32, &brightness),
brightness[y][x],
))
}
result.push(row)
}
Ok(result)
}
pub fn preview(path: String, version: Version, brightness_threshold: u8) -> anyhow::Result<()> {
let target = image::open(path).context("Could not open target image")?;
let side_len = crate::consts::side_len_of_version(version);
let scaled = target.resize_exact(side_len, side_len, image::imageops::FilterType::Gaussian);
let brightness = make_brightness_array(scaled);
let mut result = image::ImageBuffer::new(side_len, side_len);
for y in 0..side_len {
for x in 0..side_len {
result.put_pixel(
x,
y,
if brightness[y as usize][x as usize] < brightness_threshold {
Rgb([0, 0, 0])
} else {
Rgb([255 as u8, 255, 255])
},
)
}
}
result.save("preview.png").context("Could not save preview image")?;
Ok(())
}
fn make_brightness_array(image: DynamicImage) -> Vec<Vec<u8>> {
let mut brightness_array = Vec::with_capacity(image.height() as usize);
for y in 0..image.height() {
let mut row = Vec::with_capacity(image.width() as usize);
for x in 0..image.width() {
let p = image.get_pixel(x as u32, y as u32).0;
row.push(
(((299 * (p[0] as u32) + 587 * (p[1] as u32) + 114 * (p[2] as u32)) + 500) / 1000)
as u8,
)
}
brightness_array.push(row)
}
brightness_array
}
fn get_contrast(target_x: u32, target_y: u32, brightness: &Vec<Vec<u8>>) -> u32 {
let range = 5;
let mut n = 0;
let mut sum: usize = 0;
let mut sum_sequence: usize = 0;
for offset_y in 0..(range * 2) {
for offset_x in 0..(range * 2) {
let pixel_y = (target_y as i32 - range) + offset_y;
let pixel_x = (target_x as i32 - range) + offset_x;
if pixel_y >= 0
&& (pixel_y as usize) < brightness.len()
&& pixel_x >= 0
&& (pixel_x as usize) < brightness[0].len()
{
let v = brightness[pixel_y as usize][pixel_x as usize];
sum += v as usize;
sum_sequence += v as usize * v as usize;
n += 1;
}
}
}
let avg = sum / n;
let contrast = sum_sequence / n - avg * avg;
contrast as u32
}