mirror of
https://github.com/waveplate/img2irc.git
synced 2024-12-22 05:36:37 +00:00
add image transformations including crop, rotate, flip horizontal/vertical, filter, scale, and aspect ratio
This commit is contained in:
parent
34f2a1ef13
commit
bb0ba0e990
218
src/effects.rs
218
src/effects.rs
@ -1,213 +1,238 @@
|
|||||||
use crate::args;
|
use crate::args;
|
||||||
use photon_rs::{colour_spaces};
|
use photon_rs::{colour_spaces, channels, conv, effects, filters, monochrome, noise};
|
||||||
use photon_rs::{channels, conv, effects, filters, monochrome, noise};
|
use photon_rs::transform::{SamplingFilter, resize, crop, rotate, flipv, fliph};
|
||||||
use photon_rs::transform::{resize, SamplingFilter};
|
|
||||||
use photon_rs::PhotonImage;
|
use photon_rs::PhotonImage;
|
||||||
|
|
||||||
|
fn calculate_dimensions(args: &args::Args, image: &PhotonImage) -> (u32, u32) {
|
||||||
|
let original_width = image.get_width() as f32;
|
||||||
|
let original_height = image.get_height() as f32;
|
||||||
|
let original_aspect = original_width / original_height;
|
||||||
|
|
||||||
|
let base_width;
|
||||||
|
let base_height;
|
||||||
|
|
||||||
|
let aspect_ratio = if let Some(aspect) = args.aspect {
|
||||||
|
aspect.0 / aspect.1
|
||||||
|
} else {
|
||||||
|
original_aspect
|
||||||
|
};
|
||||||
|
|
||||||
|
if args.width.is_none() && args.height.is_none() {
|
||||||
|
base_width = original_width;
|
||||||
|
base_height = original_height;
|
||||||
|
} else if args.width.is_none() {
|
||||||
|
let provided_height = args.height.unwrap();
|
||||||
|
base_height = provided_height as f32;
|
||||||
|
base_width = base_height * aspect_ratio;
|
||||||
|
} else if args.height.is_none() {
|
||||||
|
let provided_width = args.width.unwrap();
|
||||||
|
base_width = provided_width as f32;
|
||||||
|
base_height = base_width / aspect_ratio;
|
||||||
|
} else {
|
||||||
|
base_width = args.width.unwrap() as f32;
|
||||||
|
base_height = args.height.unwrap() as f32;
|
||||||
|
}
|
||||||
|
|
||||||
|
let (scaled_width, scaled_height) = if let Some(scale) = args.scale {
|
||||||
|
(base_width * scale.0, base_height * scale.1)
|
||||||
|
} else {
|
||||||
|
(base_width, base_height)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Step 4: Round the scaled dimensions to the nearest integer and ensure a minimum size of 1.
|
||||||
|
let final_width = scaled_width.round().max(1.0) as u32;
|
||||||
|
let final_height = scaled_height.round().max(1.0) as u32;
|
||||||
|
|
||||||
|
(final_width, final_height)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn apply_effects(
|
pub fn apply_effects(
|
||||||
args: &args::Args,
|
args: &args::Args,
|
||||||
mut photon_image: PhotonImage,
|
mut photon_image: PhotonImage,
|
||||||
) -> PhotonImage {
|
) -> PhotonImage {
|
||||||
|
let (width, height) = calculate_dimensions(args, &photon_image);
|
||||||
|
|
||||||
|
if args.rotate != 0 {
|
||||||
|
photon_image = rotate(&photon_image, args.rotate as i32);
|
||||||
|
}
|
||||||
|
|
||||||
// Resize to width
|
if args.fliph {
|
||||||
let height =
|
fliph(&mut photon_image);
|
||||||
(args.width as f32 / photon_image.get_width() as f32 * photon_image.get_height() as f32) as u32;
|
}
|
||||||
|
|
||||||
let width = match args.qb {
|
if args.flipv {
|
||||||
true => args.width * 2,
|
flipv(&mut photon_image);
|
||||||
_ => args.width,
|
}
|
||||||
|
|
||||||
|
photon_image = resize(&photon_image, width, height, match args.filter {
|
||||||
|
args::SamplingFilter::Nearest => SamplingFilter::Nearest,
|
||||||
|
args::SamplingFilter::Triangle => SamplingFilter::Triangle,
|
||||||
|
args::SamplingFilter::CatmullRom => SamplingFilter::CatmullRom,
|
||||||
|
args::SamplingFilter::Gaussian => SamplingFilter::Gaussian,
|
||||||
|
args::SamplingFilter::Lanczos3 => SamplingFilter::Lanczos3,
|
||||||
|
});
|
||||||
|
|
||||||
|
type ColourFunc = fn(&mut PhotonImage, &str, f32);
|
||||||
|
|
||||||
|
let colour_func: ColourFunc = match args.colorspace {
|
||||||
|
args::ColourSpace::HSL => colour_spaces::hsl,
|
||||||
|
args::ColourSpace::HSV => colour_spaces::hsv,
|
||||||
|
args::ColourSpace::HSLUV => colour_spaces::hsluv,
|
||||||
|
args::ColourSpace::LCH => colour_spaces::lch,
|
||||||
};
|
};
|
||||||
|
|
||||||
photon_image = match args.qb {
|
if args.dither > 0 {
|
||||||
true => resize(&photon_image, width, height, SamplingFilter::Lanczos3),
|
effects::dither(&mut photon_image, args.dither);
|
||||||
_ => resize(&mut photon_image, width, height, SamplingFilter::Lanczos3),
|
}
|
||||||
};
|
|
||||||
|
|
||||||
// Adjust brightness
|
|
||||||
match args.brightness {
|
match args.brightness {
|
||||||
x if x > 0.0 => {
|
x if x > 0.0 => {
|
||||||
colour_spaces::hsv(&mut photon_image, "brighten", args.brightness/255.0);
|
colour_func(&mut photon_image, "lighten", args.brightness / 100.0);
|
||||||
}
|
}
|
||||||
x if x < 0.0 => {
|
x if x < 0.0 => {
|
||||||
colour_spaces::hsv(&mut photon_image, "darken", args.brightness.abs()/255.0);
|
colour_func(&mut photon_image, "darken", args.brightness.abs() / 100.0);
|
||||||
},
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust hue
|
|
||||||
if args.hue > 0.0 {
|
|
||||||
colour_spaces::hsv(&mut photon_image, "shift_hue", args.hue/360.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adjust contrast
|
|
||||||
if args.contrast != 0.0 {
|
|
||||||
effects::adjust_contrast(&mut photon_image, args.contrast);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adjust saturation
|
|
||||||
match args.saturation {
|
match args.saturation {
|
||||||
x if x > 0.0 => {
|
x if x > 0.0 => {
|
||||||
colour_spaces::hsv(&mut photon_image, "saturate", args.saturation/255.0);
|
colour_func(&mut photon_image, "saturate", args.saturation/100.0);
|
||||||
}
|
}
|
||||||
x if x < 0.0 => {
|
x if x < 0.0 => {
|
||||||
colour_spaces::hsv(&mut photon_image, "desaturate", args.saturation.abs()/255.0);
|
colour_func(&mut photon_image, "desaturate", args.saturation.abs()/100.0);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust gamma
|
if args.contrast != 0.0 {
|
||||||
|
effects::adjust_contrast(&mut photon_image, args.contrast);
|
||||||
|
}
|
||||||
|
|
||||||
|
if args.hue > 0.0 {
|
||||||
|
colour_func(&mut photon_image, "shift_hue", args.hue/360.0);
|
||||||
|
}
|
||||||
|
|
||||||
if args.gamma != 0.0 {
|
if args.gamma != 0.0 {
|
||||||
let gamma_value = 1.0 - args.gamma/255.0;
|
let gamma_value = 1.0 - args.gamma/255.0;
|
||||||
colour_spaces::gamma_correction(&mut photon_image, gamma_value, gamma_value, gamma_value);
|
colour_spaces::gamma_correction(&mut photon_image, gamma_value, gamma_value, gamma_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust dither
|
if args.crop.is_some() {
|
||||||
if args.dither > 0 {
|
let crop_args = args.crop.unwrap();
|
||||||
effects::dither(&mut photon_image, args.dither);
|
photon_image = crop(&mut photon_image, crop_args.0, crop_args.1, crop_args.2, crop_args.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust gaussian_blur
|
|
||||||
if args.gaussian_blur > 0 {
|
if args.gaussian_blur > 0 {
|
||||||
conv::gaussian_blur(&mut photon_image, args.gaussian_blur);
|
conv::gaussian_blur(&mut photon_image, args.gaussian_blur);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust pixelize
|
|
||||||
if args.pixelize > 0 {
|
if args.pixelize > 0 {
|
||||||
effects::pixelize(&mut photon_image, args.pixelize);
|
effects::pixelize(&mut photon_image, args.pixelize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust halftone
|
|
||||||
if args.halftone {
|
if args.halftone {
|
||||||
effects::halftone(&mut photon_image);
|
effects::halftone(&mut photon_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust invert
|
|
||||||
if args.invert {
|
if args.invert {
|
||||||
channels::invert(&mut photon_image);
|
channels::invert(&mut photon_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust sepia
|
|
||||||
if args.sepia {
|
if args.sepia {
|
||||||
monochrome::sepia(&mut photon_image);
|
monochrome::sepia(&mut photon_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust solarize
|
|
||||||
if args.solarize {
|
if args.solarize {
|
||||||
effects::solarize(&mut photon_image);
|
effects::solarize(&mut photon_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust normalize
|
|
||||||
if args.normalize {
|
if args.normalize {
|
||||||
effects::normalize(&mut photon_image);
|
effects::normalize(&mut photon_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust noise
|
|
||||||
if args.noise {
|
if args.noise {
|
||||||
noise::add_noise_rand(&mut photon_image);
|
noise::add_noise_rand(&mut photon_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust sharpen
|
|
||||||
if args.sharpen {
|
if args.sharpen {
|
||||||
conv::sharpen(&mut photon_image);
|
conv::sharpen(&mut photon_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust edge_detection
|
|
||||||
if args.edge_detection {
|
if args.edge_detection {
|
||||||
|
|
||||||
conv::edge_detection(&mut photon_image);
|
conv::edge_detection(&mut photon_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust emboss
|
|
||||||
if args.emboss {
|
if args.emboss {
|
||||||
conv::emboss(&mut photon_image);
|
conv::emboss(&mut photon_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust frosted_glass
|
|
||||||
if args.frosted_glass {
|
if args.frosted_glass {
|
||||||
effects::frosted_glass(&mut photon_image);
|
effects::frosted_glass(&mut photon_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust box_blur
|
|
||||||
if args.box_blur {
|
if args.box_blur {
|
||||||
conv::box_blur(&mut photon_image);
|
conv::box_blur(&mut photon_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust grayscale
|
|
||||||
if args.grayscale {
|
if args.grayscale {
|
||||||
monochrome::grayscale(&mut photon_image);
|
monochrome::grayscale(&mut photon_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust identity
|
|
||||||
if args.identity {
|
if args.identity {
|
||||||
conv::identity(&mut photon_image);
|
conv::identity(&mut photon_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust laplace
|
|
||||||
if args.laplace {
|
if args.laplace {
|
||||||
conv::laplace(&mut photon_image);
|
conv::laplace(&mut photon_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust cali
|
|
||||||
if args.cali {
|
if args.cali {
|
||||||
filters::cali(&mut photon_image);
|
filters::cali(&mut photon_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust dramatic
|
|
||||||
if args.dramatic {
|
if args.dramatic {
|
||||||
filters::dramatic(&mut photon_image);
|
filters::dramatic(&mut photon_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust firenze
|
|
||||||
if args.firenze {
|
if args.firenze {
|
||||||
filters::firenze(&mut photon_image);
|
filters::firenze(&mut photon_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust golden
|
|
||||||
if args.golden {
|
if args.golden {
|
||||||
filters::golden(&mut photon_image);
|
filters::golden(&mut photon_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust lix
|
|
||||||
if args.lix {
|
if args.lix {
|
||||||
filters::lix(&mut photon_image);
|
filters::lix(&mut photon_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust lofi
|
|
||||||
if args.lofi {
|
if args.lofi {
|
||||||
filters::lofi(&mut photon_image);
|
filters::lofi(&mut photon_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust neue
|
|
||||||
if args.neue {
|
if args.neue {
|
||||||
filters::neue(&mut photon_image);
|
filters::neue(&mut photon_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust obsidian
|
|
||||||
if args.obsidian {
|
if args.obsidian {
|
||||||
filters::obsidian(&mut photon_image);
|
filters::obsidian(&mut photon_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust pastel_pink
|
|
||||||
if args.pastel_pink {
|
if args.pastel_pink {
|
||||||
filters::pastel_pink(&mut photon_image);
|
filters::pastel_pink(&mut photon_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust ryo
|
|
||||||
if args.ryo {
|
if args.ryo {
|
||||||
filters::ryo(&mut photon_image);
|
filters::ryo(&mut photon_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust oil
|
|
||||||
match &args.oil {
|
match &args.oil {
|
||||||
Some(oil) => {
|
Some(oil) => {
|
||||||
// split oil at comma
|
|
||||||
let vals: Vec<&str> = oil.split(",").collect();
|
let vals: Vec<&str> = oil.split(",").collect();
|
||||||
|
|
||||||
// check if args.oil has 2 values
|
|
||||||
if vals.len() == 2 {
|
if vals.len() == 2 {
|
||||||
// convert oil values to i32 and f64
|
|
||||||
let radius: i32 = vals.get(0).unwrap().parse::<i32>().unwrap();
|
let radius: i32 = vals.get(0).unwrap().parse::<i32>().unwrap();
|
||||||
let intensity: f64 = vals.get(1).unwrap().parse::<f64>().unwrap();
|
let intensity: f64 = vals.get(1).unwrap().parse::<f64>().unwrap();
|
||||||
|
|
||||||
effects::oil(&mut photon_image, radius, intensity);
|
effects::oil(&mut photon_image, radius, intensity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -216,3 +241,64 @@ pub fn apply_effects(
|
|||||||
|
|
||||||
photon_image
|
photon_image
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn apply_luma_effects(args: &args::Args, mut photon_image: PhotonImage) -> PhotonImage {
|
||||||
|
let (width, height) = calculate_dimensions(args, &photon_image);
|
||||||
|
|
||||||
|
if args.rotate != 0 {
|
||||||
|
photon_image = rotate(&photon_image, args.rotate);
|
||||||
|
}
|
||||||
|
|
||||||
|
if args.fliph {
|
||||||
|
fliph(&mut photon_image);
|
||||||
|
}
|
||||||
|
|
||||||
|
if args.flipv {
|
||||||
|
flipv(&mut photon_image);
|
||||||
|
}
|
||||||
|
|
||||||
|
photon_image = resize(&photon_image, width, height, match args.filter {
|
||||||
|
args::SamplingFilter::Nearest => SamplingFilter::Nearest,
|
||||||
|
args::SamplingFilter::Triangle => SamplingFilter::Triangle,
|
||||||
|
args::SamplingFilter::CatmullRom => SamplingFilter::CatmullRom,
|
||||||
|
args::SamplingFilter::Gaussian => SamplingFilter::Gaussian,
|
||||||
|
args::SamplingFilter::Lanczos3 => SamplingFilter::Lanczos3,
|
||||||
|
});
|
||||||
|
|
||||||
|
type ColourFunc = fn(&mut PhotonImage, &str, f32);
|
||||||
|
|
||||||
|
let colour_func: ColourFunc = match args.colorspace {
|
||||||
|
args::ColourSpace::HSL => colour_spaces::hsl,
|
||||||
|
args::ColourSpace::HSV => colour_spaces::hsv,
|
||||||
|
args::ColourSpace::HSLUV => colour_spaces::hsluv,
|
||||||
|
args::ColourSpace::LCH => colour_spaces::lch,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
if args.luma_invert {
|
||||||
|
channels::invert(&mut photon_image);
|
||||||
|
}
|
||||||
|
|
||||||
|
if args.luma_contrast != 0.0 {
|
||||||
|
effects::adjust_contrast(&mut photon_image, args.luma_contrast);
|
||||||
|
}
|
||||||
|
|
||||||
|
if args.luma_gamma != 0.0 {
|
||||||
|
let gamma_value = 1.0 - args.luma_gamma/255.0;
|
||||||
|
colour_spaces::gamma_correction(&mut photon_image, gamma_value, gamma_value, gamma_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if args.luma_brightness > 0.0 {
|
||||||
|
colour_func(&mut photon_image, "lighten", args.luma_brightness/100.0);
|
||||||
|
} else if args.luma_brightness < 0.0 {
|
||||||
|
colour_func(&mut photon_image, "darken", args.luma_brightness.abs()/100.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if args.luma_saturation < 0.0 {
|
||||||
|
colour_func(&mut photon_image, "saturate", args.luma_saturation.abs()/100.0);
|
||||||
|
} else if args.luma_saturation > 0.0 {
|
||||||
|
colour_func(&mut photon_image, "desaturate", args.luma_saturation/100.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
photon_image
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user