Pi66

Home | Repos | About | Blog | Gaza

walrs
pywal but if its Fast-Minimal-Simple
git clone https://git.pi66.xyz/walrs

About | Files | Commits | Refs | License


add option to change the backend

Author: pixel2175
Date: 2025-05-31 20:12
commit: ae7d97f7

Stat

M src/get_colors.rs 153 +95 -58

Diff

diff --git a/src/get_colors.rs b/src/get_colors.rs
index 3d755f6..6b04670 100644
--- a/src/get_colors.rs
+++ b/src/get_colors.rs
@@ -1,5 +1,6 @@
 use crate::utils::warning;
 use color_thief::ColorFormat;
+use image::RgbaImage;
 use kmeans_colors::get_kmeans;
 use palette::{FromColor, IntoColor, Lab, Srgb};
 use palette_extract::{MaxColors, Quality};
@@ -31,41 +32,7 @@ fn to_gray(r: u8, g: u8, b: u8, v: u8) -> (u8, u8, u8) {
     (gray, gray, gray)
 }

-fn generate_variation(color: (u8, u8, u8), offset: i8) -> (u8, u8, u8) { - adjust_rgb(color.0, color.1, color.2, offset, 50) -} - -pub fn get_colors( ...

Show all

diff --git a/src/get_colors.rs b/src/get_colors.rs
index 3d755f6..6b04670 100644
--- a/src/get_colors.rs
+++ b/src/get_colors.rs
@@ -1,5 +1,6 @@
 use crate::utils::warning;
 use color_thief::ColorFormat;
+use image::RgbaImage;
 use kmeans_colors::get_kmeans;
 use palette::{FromColor, IntoColor, Lab, Srgb};
 use palette_extract::{MaxColors, Quality};
@@ -31,41 +32,7 @@ fn to_gray(r: u8, g: u8, b: u8, v: u8) -> (u8, u8, u8) {
     (gray, gray, gray)
 }

-fn generate_variation(color: (u8, u8, u8), offset: i8) -> (u8, u8, u8) { - adjust_rgb(color.0, color.1, color.2, offset, 50) -} - -pub fn get_colors( - image_path: &str, - send: bool, - brightness: Option<i8>, - saturation: Option<i8>, -) -> (Vec<(u8, u8, u8)>, u8) { - let core_image = match image::open(image_path) { - Ok(img) => img, - Err(_) => { - let data = read(image_path).unwrap(); - match image::guess_format(&data) { - Ok(fmt) => image::load_from_memory_with_format(&data, fmt).unwrap(), - Err(_) => { - warning("Image", "Unsupported or corrupted image format", send); - exit(1); - } - } - } - }; - - // resize the image - let image = core_image.resize( - 400, - (core_image.height() as f32 * (400 as f32 / core_image.width() as f32)) as u32, - image::imageops::FilterType::Lanczos3, - ); - - let native_rgba = image.to_rgba8(); - let alpha = &native_rgba.get_pixel(0, 0)[3]; - let mut collect_rgb: Vec<(u8, u8, u8)> = Vec::new(); - +fn kmeans_colors(len: u8, native_rgba: RgbaImage) -> Vec<(u8, u8, u8)> { let pixels_kmeans: Vec<Lab> = native_rgba .pixels() .filter(|p| p.0[3] > 0) // Filter out transparent pixels @@ -82,48 +49,118 @@ pub fn get_colors( }) .collect();

- let palette_kmeans: Vec<Srgb> = get_kmeans(10, 20, 1.0, false, &pixels_kmeans, 0) + let palette_kmeans: Vec<Srgb> = get_kmeans(10, len as usize, 1.0, false, &pixels_kmeans, 0) .centroids .iter() .map(|&lab| Srgb::from_color(lab)) .collect();

- for color in &palette_kmeans { - let (r, g, b) = ( - (color.red * 255.0).round() as u8, - (color.green * 255.0).round() as u8, - (color.blue * 255.0).round() as u8, - ); - collect_rgb.push((r, g, b)) - } + return palette_kmeans + .iter() + .map(|color| { + let (r, g, b) = ( + (color.red * 255.0).round() as u8, + (color.green * 255.0).round() as u8, + (color.blue * 255.0).round() as u8, + ); + (r, g, b) + }) + .collect::<Vec<(u8, u8, u8)>>(); +}

+fn color_thief_colors(len: u8, native_rgba: RgbaImage) -> Vec<(u8, u8, u8)> { let palette_extract = palette_extract::get_palette_with_options( &native_rgba, palette_extract::PixelEncoding::Rgba, Quality::new(5), - MaxColors::new(10), + MaxColors::new(len), palette_extract::PixelFilter::White, ); - let palette_thief = color_thief::get_palette(&native_rgba, ColorFormat::Rgba, 5, 10);

- for color in &palette_extract { - collect_rgb.push((color.r, color.g, color.b)); - } + return palette_extract + .iter() + .map(|color| (color.r, color.g, color.b)) + .collect::<Vec<(u8, u8, u8)>>(); +} + +fn palette_extract_colors(len: u8, native_rgba: RgbaImage, send: bool) -> Vec<(u8, u8, u8)> { + let palette_thief = color_thief::get_palette(&native_rgba, ColorFormat::Rgba, 5, len) + .unwrap_or_else(|_| { + warning("Backend", "palette thief can't extract the palette", send); + exit(1) + }); + + return palette_thief + .iter() + .map(|color| (color.r, color.g, color.b)) + .collect::<Vec<(u8, u8, u8)>>(); +}

- if let Ok(ref colors) = palette_thief { - for color in colors { - collect_rgb.push((color.r, color.g, color.b)); +fn extract_colors(len: u8, backend: &str, native_rgba: RgbaImage, send: bool) -> Vec<(u8, u8, u8)> { + match backend { + "kmeans" => kmeans_colors(10, native_rgba), + "color_thief" => color_thief_colors(10, native_rgba), + "palette_extract" => palette_extract_colors(10, native_rgba, send), + "all" => { + let mut collected: Vec<(u8, u8, u8)> = Vec::new(); + kmeans_colors(len, native_rgba.clone()) + .iter() + .for_each(|c| { + collected.push(*c); + }); + color_thief_colors(len / 3 as u8, native_rgba.clone()) + .iter() + .for_each(|c| { + collected.push(*c); + }); + palette_extract_colors(len / 3 as u8, native_rgba, send) + .iter() + .for_each(|c| { + collected.push(*c); + }); + collected + } + &_ => { + warning("Backend", "this backend is not exists", send); + exit(1) } } +}

- collect_rgb = remove_duplicates(collect_rgb); +pub fn get_colors( + image_path: &str, + backend: &str, + send: bool, + brightness: Option<i8>, + saturation: Option<i8>, +) -> (Vec<(u8, u8, u8)>, u8) { + let core_image = match image::open(image_path) { + Ok(img) => img, + Err(_) => { + let data = read(image_path).unwrap(); + match image::guess_format(&data) { + Ok(fmt) => image::load_from_memory_with_format(&data, fmt).unwrap(), + Err(_) => { + warning("Image", "Unsupported or corrupted image format", send); + exit(1) + } + } + } + }; + + let image = core_image.resize( + 400, + (core_image.height() as f32 * (400 as f32 / core_image.width() as f32)) as u32, + image::imageops::FilterType::Lanczos3, + );

- let mut i = 0; + let native_rgba = image.to_rgba8(); + let alpha = &native_rgba.get_pixel(0, 0)[3]; + let mut collect_rgb: Vec<(u8, u8, u8)> = extract_colors(30, backend, native_rgba.clone(), send); + + collect_rgb = remove_duplicates(collect_rgb); while collect_rgb.len() <= 21 { - let base = collect_rgb[i % collect_rgb.len()]; - let variation = generate_variation(base, 10 * (i as i8 + 1)); - collect_rgb.push(variation); - i += 1; + collect_rgb.push(extract_colors(1, backend, native_rgba.clone(), send)[0]); }

 collect&#95;rgb.sort&#95;by(&#124;a, b&#124; {

// Created by Pi66

// Copyright ©Pi66 2026