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 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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue