Convert images into black and white
This commit is contained in:
parent
dd38ff0ccd
commit
ef99bee0d3
2 changed files with 96 additions and 1 deletions
55
src/lib.rs
Normal file
55
src/lib.rs
Normal 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;
|
||||
}
|
||||
}
|
||||
42
src/main.rs
42
src/main.rs
|
|
@ -6,15 +6,54 @@ use std::{
|
|||
use clap::Parser;
|
||||
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)]
|
||||
/// 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)]
|
||||
enum Cmd {
|
||||
Bw(BwCmd),
|
||||
}
|
||||
|
||||
impl Cmd {
|
||||
fn run(self, image: RgbaImage) -> RgbaImage {
|
||||
match self {
|
||||
Cmd::Bw(cmd) => cmd.run(image),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, clap::Parser)]
|
||||
struct Args {
|
||||
/// Load image from file instead of stdin.
|
||||
|
|
@ -70,5 +109,6 @@ fn save_image(out: &Option<PathBuf>, image: RgbaImage) {
|
|||
fn main() {
|
||||
let args = Args::parse();
|
||||
let image = load_image(&args.r#in);
|
||||
let image = args.cmd.run(image);
|
||||
save_image(&args.out, image);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue