extern crate image;
extern crate imageproc;
use std::env;
use std::path::Path;
use image::{Luma, open, Rgb};
use imageproc::map::map_colors;
use imageproc::pixelops::weighted_sum;
pub fn tint(gray: Luma<u8>, color: Rgb<u8>) -> Rgb<u8> {
let dist_from_mid = ((gray[0] as f32 - 128f32).abs()) / 255f32;
let scale_factor = 1f32 - 4f32 * dist_from_mid.powi(2);
weighted_sum(Rgb([gray[0]; 3]), color, 1.0, scale_factor)
}
pub fn color_gradient(gray: Luma<u8>, low: Rgb<u8>, mid: Rgb<u8>, high: Rgb<u8>) -> Rgb<u8> {
let fraction = gray[0] as f32 / 255f32;
let (lower, upper, offset) = if fraction < 0.5 { (low, mid, 0.0) } else { (mid, high, 0.5) };
let right_weight = 2.0 * (fraction - offset);
let left_weight = 1.0 - right_weight;
weighted_sum(lower, upper, left_weight, right_weight)
}
fn main() {
let arg = if env::args().count() == 2 {
env::args().nth(1).unwrap()
} else {
panic!("Please enter an input file")
};
let path = Path::new(&arg);
let image = open(path)
.ok()
.expect(&format!("Could not load image at {:?}", path))
.to_luma();
let blue = Rgb([0u8, 0u8, 255u8]);
let tinted = map_colors(&image, |pix| tint(pix, blue));
let _ = tinted.save(path.with_file_name("tinted.png")).unwrap();
let black = Rgb([0u8, 0u8, 0u8]);
let red = Rgb([255u8, 0u8, 0u8]);
let yellow = Rgb([255u8, 255u8, 0u8]);
let gradient = map_colors(&image, |pix| color_gradient(pix, black, red, yellow));
let _ = gradient.save(path.with_file_name("gradient.png")).unwrap();
}