diff --git a/Cargo.lock b/Cargo.lock index cc48f3a..56eabb4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -206,16 +206,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crossbeam-channel" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - [[package]] name = "crossbeam-deque" version = "0.8.2" @@ -709,9 +699,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.6.1" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" dependencies = [ "either", "rayon-core", @@ -719,14 +709,12 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.10.1" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] @@ -749,6 +737,7 @@ dependencies = [ "clap", "glob", "image", + "rayon", "serde", "serde_json", "smithay-client-toolkit", diff --git a/Cargo.toml b/Cargo.toml index d533cee..f31a3ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ image = "0.24.8" toml = "0.8.9" serde = { version = "1.0.196", features = ["derive"] } serde_json = "1.0.113" +rayon = "1.8.1" # makes image lib faster for dev [profile.dev-unopt] @@ -20,4 +21,4 @@ opt-level = 3 # Ref: https://github.com/johnthagen/min-sized-rust [profile.release] strip = true -lto = true \ No newline at end of file +lto = true diff --git a/src/worker.rs b/src/worker.rs index d327511..01b6f90 100644 --- a/src/worker.rs +++ b/src/worker.rs @@ -6,6 +6,7 @@ use crate::wpaperd::Wpaperd; use crate::Config; use glob::glob; use image::{imageops::FilterType, DynamicImage, GenericImageView}; +use rayon::prelude::{IntoParallelRefIterator, ParallelIterator}; use std::cmp; use std::collections::hash_map; use std::env; @@ -192,39 +193,48 @@ impl Worker { Crop image for screens and push them to the result vector, taking into account negative offsets + Doing it in parallel using rayon for speedup */ - let mut result = Vec::with_capacity(self.monitors.len()); - for monitor in &self.monitors { - // convert for cropping - let adjusted_x = u32::try_from(origin_x as i32 + monitor.x) - .map_err(|_| "x adjustment out of range")?; - let adjusted_y = u32::try_from(origin_y as i32 + monitor.y) - .map_err(|_| "y adjustment out of range")?; - // crop the image - let cropped_image = img.crop( - adjusted_x + resize_offset_x, - adjusted_y + resize_offset_y, - monitor.width, - monitor.height, - ); - - // get full image path - let path_image = format!("{}/rwps_{}_{}.png", save_path, &self.hash, &monitor.name,); - - // save it - cropped_image - .save(&path_image) - .map_err(|err| err.to_string())?; + let result: Vec> = self + .monitors + .par_iter() + .map(|monitor| -> Result { + let adjusted_x = u32::try_from(origin_x as i32 + monitor.x) + .map_err(|_| "x adjustment out of range")?; + let adjusted_y = u32::try_from(origin_y as i32 + monitor.y) + .map_err(|_| "y adjustment out of range")?; + + // crop to size + let cropped_image = img.crop_imm( + adjusted_x + resize_offset_x, + adjusted_y + resize_offset_y, + monitor.width, + monitor.height, + ); + + // export to file + let path_image = format!("{}/rwps_{}_{}.png", save_path, &self.hash, &monitor.name); + cropped_image + .save(&path_image) + .map_err(|err| err.to_string())?; - // push to result vector - result.push(ResultPaper { - monitor_name: format!("{}", &monitor.name), - full_path: path_image, - image: cropped_image, + Ok(ResultPaper { + monitor_name: format!("{}", &monitor.name), + full_path: path_image, + image: cropped_image, + }) }) + .collect(); + + if &result.iter().all(Result::is_ok) == &true { + let converted: Vec = result + .into_iter() + .filter_map(|result| result.ok()) + .collect(); + Ok(converted) + } else { + Err("Cropping Error".to_string()) } - - Ok(result) } fn cleanup_cache(&self) {