fix brightness, contrast, saturation, hue, gamma and remove opacity

This commit is contained in:
Anatoly Bazarov 2023-05-02 08:17:10 -07:00
parent 577d82a5ef
commit ff9ac2667f
5 changed files with 71 additions and 53 deletions

View File

@ -1,10 +1,16 @@
[package] [package]
name = "img2irc" name = "img2irc"
version = "0.2.0" version = "1.0.0"
authors = ["anatolybazarov"] authors = ["anatolybazarov"]
github = "https://github.com/anatolybazarov/img2irc" github = "https://github.com/anatolybazarov/img2irc"
edition = "2021" edition = "2021"
[profile.release]
lto = true
codegen-units = 1
opt-level = "z"
strip = true # Automatically strip symbols from the binary.
[dependencies] [dependencies]
tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] } tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] }
reqwest = "0.11.14" reqwest = "0.11.14"

View File

@ -1,4 +1,4 @@
# img2irc (0.2.0) # img2irc (1.0.0)
![img2irc preview](https://i.imgur.com/oetHhMB.png) ![img2irc preview](https://i.imgur.com/oetHhMB.png)
img2irc is a utility which converts images to halfblock irc/ansi art, with a lot of post-processing filters img2irc is a utility which converts images to halfblock irc/ansi art, with a lot of post-processing filters
@ -14,14 +14,15 @@ the `irc` mode has 99 colours, the `ansi` mode has 256, `ansi24` has 16777216
| option | description | default value | | option | description | default value |
| ------ | ----------- | ------------- | | ------ | ----------- | ------------- |
| `<IMAGE>` | image url or file path | none | | `<IMAGE>` | image url or file path | none |
| `-r, --render <RENDER>` | render type (irc, ansi, ansi24) | irc | | `--irc` | irc render type | true |
| `--ansi` | 8-bit ansi render type | false |
| `--ansi24` | 24-bit ansi render type | false |
| `-w, --width <WIDTH>` | output image width in columns | 50 | | `-w, --width <WIDTH>` | output image width in columns | 50 |
| `-b, --brightness=<BRIGHTNESS>` | adjust brightness (-255 to 255) | 0 | | `-b, --brightness=<BRIGHTNESS>` | adjust brightness (-255 to 255) | 0 |
| `-H, --hue=<HUE>` | adjust hue (-180 to 180) | 0 |
| `-c, --contrast=<CONTRAST>` | adjust contrast (-255 to 255) | 0 | | `-c, --contrast=<CONTRAST>` | adjust contrast (-255 to 255) | 0 |
| `-s, --saturation=<SATURATION>` | adjust saturation (-255 to 255) | 0 | | `-s, --saturation=<SATURATION>` | adjust saturation (-255 to 255) | 0 |
| `-o, --opacity=<OPACITY>` | adjust opacity (-255 to 255) | 0 | | `-H, --hue <HUE>` | rotate hue (0 to 360) | 0 |
| `-g, --gamma=<GAMMA>` | adjust gamma (-255 to 255) | 0 | | `-g, --gamma <GAMMA>` | adjust gamma (0 to 255) | 0 |
| `--dither <DITHER>` | dithering (1 to 8) | 0 | | `--dither <DITHER>` | dithering (1 to 8) | 0 |
| `--pixelize <PIXELIZE>` | pixelize pixel size | 0 | | `--pixelize <PIXELIZE>` | pixelize pixel size | 0 |
| `--gaussian-blur <GAUSSIAN_BLUR>` | gaussian blur radius | 0 | | `--gaussian-blur <GAUSSIAN_BLUR>` | gaussian blur radius | 0 |

View File

@ -7,37 +7,41 @@ pub struct Args {
#[arg(index = 1)] #[arg(index = 1)]
pub image: String, pub image: String,
/// render type (irc, ansi) /// irc
#[arg(short, long)] #[arg(long, default_value_t = false)]
pub render: Option<String>, pub irc: bool,
/// 8-bit ansi
#[arg(long, default_value_t = false)]
pub ansi: bool,
/// 24-bit ansi
#[arg(long, default_value_t = false)]
pub ansi24: bool,
/// image width to resize to /// image width to resize to
#[arg(short, long, default_value_t = 50)] #[arg(short, long, default_value_t = 50)]
pub width: u32, pub width: u32,
/// brightness (-255 to 255) /// brightness (-255 to 255)
#[arg(short, long, require_equals = true, default_value_t = 0)] #[arg(short, long, require_equals = true, default_value_t = 0.0)]
pub brightness: i16, pub brightness: f32,
/// hue (-180 to 180)
#[arg(short = 'H', long, require_equals = true, default_value_t = 0)]
pub hue: i16,
/// contrast (-255 to 255) /// contrast (-255 to 255)
#[arg(short, long, require_equals = true, default_value_t = 0)] #[arg(short, long, require_equals = true, default_value_t = 0.0)]
pub contrast: i16, pub contrast: f32,
/// saturation (-255 to 255) /// saturation (-255 to 255)
#[arg(short, long, require_equals = true, default_value_t = 0)] #[arg(short, long, require_equals = true, default_value_t = 0.0)]
pub saturation: i16, pub saturation: f32,
/// opacity (-255 to 255) /// hue (0 to 360)
#[arg(short, long, require_equals = true, default_value_t = 0)] #[arg(short = 'H', long, default_value_t = 0.0)]
pub opacity: i16, pub hue: f32,
/// gamma (-255 to 255) /// gamma (0 to 255)
#[arg(short, long, require_equals = true, default_value_t = 0)] #[arg(short, long, default_value_t = 0.0)]
pub gamma: i16, pub gamma: f32,
/// dither (1 to 8) /// dither (1 to 8)
#[arg(long, default_value_t = 0)] #[arg(long, default_value_t = 0)]

View File

@ -1,5 +1,6 @@
use crate::args; use crate::args;
use photon_rs::{channels, channels::alter_channels, conv, effects, filters, monochrome, noise}; use photon_rs::{colour_spaces};
use photon_rs::{channels, conv, effects, filters, monochrome, noise};
use photon_rs::transform::{resize, SamplingFilter}; use photon_rs::transform::{resize, SamplingFilter};
use photon_rs::PhotonImage; use photon_rs::PhotonImage;
@ -15,33 +16,41 @@ pub fn apply_effects(
photon_image = resize(&mut photon_image, args.width, height, SamplingFilter::Lanczos3); photon_image = resize(&mut photon_image, args.width, height, SamplingFilter::Lanczos3);
// Adjust brightness // Adjust brightness
if args.brightness != 0 { match args.brightness {
alter_channels(&mut photon_image, args.brightness, args.brightness, args.brightness); x if x > 0.0 => {
colour_spaces::hsv(&mut photon_image, "brighten", args.brightness/255.0);
}
x if x < 0.0 => {
colour_spaces::hsv(&mut photon_image, "darken", args.brightness.abs()/255.0);
},
_ => {}
} }
// Adjust hue // Adjust hue
if args.hue != 0 { if args.hue > 0.0 {
alter_channels(&mut photon_image, args.hue, args.hue, args.hue); colour_spaces::hsv(&mut photon_image, "shift_hue", args.hue/360.0);
} }
// Adjust contrast // Adjust contrast
if args.contrast != 0 { if args.contrast != 0.0 {
alter_channels(&mut photon_image, args.contrast, args.contrast, args.contrast); effects::adjust_contrast(&mut photon_image, args.contrast);
} }
// Adjust saturation // Adjust saturation
if args.saturation != 0 { match args.saturation {
alter_channels(&mut photon_image, args.saturation, args.saturation, args.saturation); x if x > 0.0 => {
} colour_spaces::hsv(&mut photon_image, "saturate", args.saturation/255.0);
}
// Adjust opacity x if x < 0.0 => {
if args.opacity != 0 { colour_spaces::hsv(&mut photon_image, "desaturate", args.saturation.abs()/255.0);
alter_channels(&mut photon_image, args.opacity, args.opacity, args.opacity); }
_ => {}
} }
// Adjust gamma // Adjust gamma
if args.gamma != 0 { if args.gamma != 0.0 {
alter_channels(&mut photon_image, args.gamma, args.gamma, args.gamma); let gamma_value = 1.0 - args.gamma/255.0;
colour_spaces::gamma_correction(&mut photon_image, gamma_value, gamma_value, gamma_value);
} }
// Adjust dither // Adjust dither
@ -51,7 +60,6 @@ pub fn apply_effects(
// Adjust gaussian_blur // 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);
} }

View File

@ -22,18 +22,17 @@ async fn main() {
); );
let canvas = draw::AnsiImage::new(image); let canvas = draw::AnsiImage::new(image);
match &args.render {
None => println!("{}", draw::irc_draw(canvas).as_str()), if args.irc {
Some(ref render) => match render.as_str() { println!("{}", draw::irc_draw(canvas).as_str());
"irc" => println!("{}", draw::irc_draw(canvas).as_str()), } else if args.ansi {
"ansi" => println!("{}", draw::ansi_draw_8bit(canvas).as_str()), println!("{}", draw::ansi_draw_8bit(canvas).as_str());
"ansi24" => println!("{}", draw::ansi_draw_24bit(canvas).as_str()), } else if args.ansi24 {
_ => { println!("{}", draw::ansi_draw_24bit(canvas).as_str());
eprintln!("Error: invalid render type"); } else {
exit(1); println!("{}", draw::irc_draw(canvas).as_str());
}
},
} }
} }
Err(e) => { Err(e) => {
eprintln!("Error: {}", e); eprintln!("Error: {}", e);