From f8a479f58b9fd584df257c919327495cdf7dc0e9 Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Sat, 19 Nov 2022 16:59:26 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=BC=95=E5=85=A5=E5=BC=82=E6=AD=A5?= =?UTF-8?q?=E8=BF=90=E8=A1=8C=E6=97=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/Cargo.lock | 67 ++++++++++++++++++++++++++++++-------- src-tauri/Cargo.toml | 6 ++-- src-tauri/src/main.rs | 75 ++++++++++++++++++++++--------------------- 3 files changed, 97 insertions(+), 51 deletions(-) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 9476966..552d2c2 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -1439,6 +1439,18 @@ dependencies = [ "adler", ] +[[package]] +name = "mio" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" +dependencies = [ + "libc", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.42.0", +] + [[package]] name = "native-tls" version = "0.2.11" @@ -2178,16 +2190,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "repng" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd57cd2cb5cc699b3eb4824d654e5a32f3bc013766da4966f71fe94805abbda" -dependencies = [ - "byteorder", - "flate2", -] - [[package]] name = "rfd" version = "0.10.0" @@ -2300,12 +2302,14 @@ dependencies = [ "bmp", "once_cell", "paris", - "repng", "scrap", "serde", "serde_json", "tauri", "tauri-build", + "tokio", + "tracing", + "tracing-subscriber", "webp", ] @@ -2517,6 +2521,15 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "signal-hook-registry" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +dependencies = [ + "libc", +] + [[package]] name = "siphasher" version = "0.3.10" @@ -2538,6 +2551,16 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +[[package]] +name = "socket2" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +dependencies = [ + "libc", + "winapi 0.3.9", +] + [[package]] name = "soup2" version = "0.2.1" @@ -3020,15 +3043,33 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.21.2" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" +checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3" dependencies = [ "autocfg", "bytes", + "libc", "memchr", + "mio", "num_cpus", + "parking_lot", "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "winapi 0.3.9", +] + +[[package]] +name = "tokio-macros" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index f85773c..caf5be7 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -15,16 +15,18 @@ tauri-build = { version = "1.1", features = [] } [dependencies] serde_json = "1.0" -serde = { version = "1.0", features = ["derive"] } +serde = { version = "1.0", features = ["derive", "rc"] } tauri = { version = "1.1", features = ["api-all"] } scrap = "0.5" -repng = "0.2.2" bmp = "0.5.0" webp = "0.2.2" base64 = "0.13.1" anyhow = "1.0.66" once_cell = "1.16.0" paris = { version = "1.5", features = ["timestamps", "macros"] } +tokio = { version = "1.22.0", features = ["full"] } +tracing = "0.1.37" +tracing-subscriber = "0.3.16" [features] # by default Tauri runs in production mode diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 8d64119..bf7305d 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -6,14 +6,11 @@ mod screen_color_picker; use paris::*; -use screen_color_picker::{Screen, ScreenColorPicker}; -use std::time::Instant; - -// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command -#[tauri::command] -fn greet(name: &str) -> String { - format!("Hello, {}! You've been greeted from Rust!", name) -} +use screen_color_picker::ScreenColorPicker; +use std::{ + sync::{Arc, Mutex}, + time::Instant, +}; #[tauri::command] fn refresh_displays() { @@ -26,41 +23,55 @@ fn refresh_displays() { } #[tauri::command] -fn take_snapshot() -> Vec { +async fn take_snapshot() -> Arc>> { let start = Instant::now(); - let screenshots = match ScreenColorPicker::global().take_screenshots_for_all() { + let screenshot_futures = match ScreenColorPicker::global().take_screenshots_for_all() { Ok(bitmaps) => { info!("bitmaps len: {}", bitmaps.len()); match ScreenColorPicker::global().screens.lock() { - Ok(screens) => Vec::from_iter( - screens - .iter() - .enumerate() - .map(|(index, screen)| bitmap_to_webp_base64(screen, &bitmaps[index])), - ), + Ok(screens) => { + Some(Vec::from_iter(screens.iter().enumerate().map( + |(index, screen)| bitmap_to_webp_base64(screen.width, screen.height, bitmaps[index].to_vec()), + ))) + } Err(error) => { error!("can not lock screens. {}", error); - Vec::::new() + None } } } Err(error) => { error!("can not take screenshots for all. {}", error); - Vec::::new() + None } }; - println!("运行耗时: {:?}", start.elapsed()); - screenshots + match screenshot_futures { + Some(futures) => { + let mut handles = Vec::with_capacity(futures.len()); + + for fut in futures { + handles.push(tokio::spawn(fut)); + } + + let mut results = Vec::with_capacity(handles.len()); + for handle in handles { + results.push(handle.await.unwrap()); + } + println!("运行耗时: {:?}", start.elapsed()); + Arc::new(Mutex::new(results)) + } + None => Arc::new(Mutex::new(Vec::new())), + } } -fn bitmap_to_webp_base64(screen: &Screen, bitmap: &Vec) -> String { - let mut bitflipped = Vec::with_capacity(screen.width * screen.height * 3); - let stride = bitmap.len() / screen.height; +async fn bitmap_to_webp_base64(width: usize, height: usize, bitmap: Vec) -> String { + let mut bitflipped = Vec::with_capacity(width * height * 3); + let stride = bitmap.len() / height; // let mut img = Image::new(w as u32, h as u32); - for y in 0..screen.height { - for x in 0..screen.width { + for y in 0..height { + for x in 0..width { let i = stride * y + 4 * x; bitflipped.extend_from_slice(&[bitmap[i + 2], bitmap[i + 1], bitmap[i]]); // img.set_pixel( @@ -71,22 +82,14 @@ fn bitmap_to_webp_base64(screen: &Screen, bitmap: &Vec) -> String { } } - let webp_memory = webp::Encoder::from_rgb( - bitflipped.as_slice(), - screen.width as u32, - screen.height as u32, - ) - .encode(100.0); + let webp_memory = + webp::Encoder::from_rgb(bitflipped.as_slice(), width as u32, height as u32).encode(100.0); return base64::encode(&*webp_memory); } fn main() { tauri::Builder::default() - .invoke_handler(tauri::generate_handler![ - greet, - take_snapshot, - refresh_displays - ]) + .invoke_handler(tauri::generate_handler![take_snapshot, refresh_displays]) .run(tauri::generate_context!()) .expect("error while running tauri application"); }