47 lines
1.6 KiB
Rust
47 lines
1.6 KiB
Rust
use base64::{engine::general_purpose::STANDARD as BASE64, Engine as _};
|
|
use std::fs;
|
|
use std::process::Command;
|
|
use tauri::{AppHandle, Emitter, Runtime};
|
|
|
|
/// Takes a screenshot of a selected area and returns the image data as base64
|
|
pub fn take_area_screenshot<R: Runtime>(app: &AppHandle<R>) -> Result<String, String> {
|
|
// Create a temporary file path
|
|
let temp_dir = std::env::temp_dir();
|
|
let timestamp = chrono::Local::now().format("%Y%m%d_%H%M%S");
|
|
let temp_file = temp_dir.join(format!("haystack_screenshot_{}.png", timestamp));
|
|
|
|
// Use screencapture command with -i flag for interactive selection
|
|
let output = Command::new("screencapture")
|
|
.arg("-i") // interactive selection
|
|
.arg("-x") // don't play sound
|
|
.arg("-o") // don't show cursor
|
|
.arg("-r") // don't add shadow
|
|
.arg(temp_file.to_str().unwrap())
|
|
.output()
|
|
.map_err(|e| format!("Failed to execute screencapture: {}", e))?;
|
|
|
|
if !output.status.success() {
|
|
return Err(format!(
|
|
"screencapture failed: {}",
|
|
String::from_utf8_lossy(&output.stderr)
|
|
));
|
|
}
|
|
|
|
// Read the captured image
|
|
let contents =
|
|
fs::read(&temp_file).map_err(|e| format!("Failed to read screenshot file: {}", e))?;
|
|
|
|
// Convert to base64
|
|
let base64_string = BASE64.encode(&contents);
|
|
|
|
// Clean up the temporary file
|
|
if let Err(e) = fs::remove_file(&temp_file) {
|
|
println!("Warning: Failed to remove temporary screenshot file: {}", e);
|
|
}
|
|
|
|
app.emit("png-processed", base64_string.clone())
|
|
.map_err(|e| format!("Failed to emit event: {}", e))?;
|
|
|
|
Ok(base64_string)
|
|
}
|