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
Show less
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(
...
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_rgb.sort_by(|a, b| {