Convert images into black and white

This commit is contained in:
Joscha 2023-07-30 17:13:23 +02:00
parent dd38ff0ccd
commit ef99bee0d3
2 changed files with 96 additions and 1 deletions

55
src/lib.rs Normal file
View file

@ -0,0 +1,55 @@
use image::RgbaImage;
use palette::{Hsl, IntoColor, Lab, LinSrgb, Oklab, Srgb};
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum BwMethod {
SrgbAverage,
LinSrgbAverage,
Hsl,
Cielab,
Oklab,
}
impl BwMethod {
fn to_bw(self, pixel: Srgb) -> Srgb {
match self {
Self::SrgbAverage => {
let value = (pixel.red + pixel.green + pixel.blue) / 3.0;
Srgb::new(value, value, value)
}
Self::LinSrgbAverage => {
let pixel: LinSrgb = pixel.into_color();
let value = (pixel.red + pixel.green + pixel.blue) / 3.0;
LinSrgb::new(value, value, value).into_color()
}
Self::Hsl => {
let mut pixel: Hsl = pixel.into_color();
pixel.saturation = 0.0;
pixel.into_color()
}
Self::Cielab => {
let mut pixel: Lab = pixel.into_color();
pixel.a = 0.5;
pixel.b = 0.5;
pixel.into_color()
}
Self::Oklab => {
let mut pixel: Oklab = pixel.into_color();
pixel.a = 0.0;
pixel.b = 0.0;
pixel.into_color()
}
}
}
}
pub fn bw(image: &mut RgbaImage, method: BwMethod) {
for pixel in image.pixels_mut() {
let [r, g, b, _] = pixel.0;
let srgb = Srgb::new(r, g, b).into_format::<f32>();
let srgb = method.to_bw(srgb).into_format::<u8>();
pixel.0[0] = srgb.red;
pixel.0[1] = srgb.green;
pixel.0[2] = srgb.blue;
}
}

View file

@ -6,15 +6,54 @@ use std::{
use clap::Parser; use clap::Parser;
use image::{ImageFormat, RgbaImage}; use image::{ImageFormat, RgbaImage};
#[derive(Debug, Clone, Copy, clap::ValueEnum)]
enum BwMethod {
SrgbAverage,
LinSrgbAverage,
Hsl,
Cielab,
Oklab,
}
impl From<BwMethod> for mark::BwMethod {
fn from(value: BwMethod) -> Self {
match value {
BwMethod::SrgbAverage => mark::BwMethod::SrgbAverage,
BwMethod::LinSrgbAverage => mark::BwMethod::LinSrgbAverage,
BwMethod::Hsl => mark::BwMethod::Hsl,
BwMethod::Cielab => mark::BwMethod::Cielab,
BwMethod::Oklab => mark::BwMethod::Oklab,
}
}
}
#[derive(Debug, clap::Parser)] #[derive(Debug, clap::Parser)]
/// Convert images into black and white. /// Convert images into black and white.
struct BwCmd {} struct BwCmd {
#[arg(long, short)]
method: BwMethod,
}
impl BwCmd {
fn run(self, mut image: RgbaImage) -> RgbaImage {
mark::bw(&mut image, self.method.into());
image
}
}
#[derive(Debug, clap::Parser)] #[derive(Debug, clap::Parser)]
enum Cmd { enum Cmd {
Bw(BwCmd), Bw(BwCmd),
} }
impl Cmd {
fn run(self, image: RgbaImage) -> RgbaImage {
match self {
Cmd::Bw(cmd) => cmd.run(image),
}
}
}
#[derive(Debug, clap::Parser)] #[derive(Debug, clap::Parser)]
struct Args { struct Args {
/// Load image from file instead of stdin. /// Load image from file instead of stdin.
@ -70,5 +109,6 @@ fn save_image(out: &Option<PathBuf>, image: RgbaImage) {
fn main() { fn main() {
let args = Args::parse(); let args = Args::parse();
let image = load_image(&args.r#in); let image = load_image(&args.r#in);
let image = args.cmd.run(image);
save_image(&args.out, image); save_image(&args.out, image);
} }