截图模块初始化

This commit is contained in:
zhongluofeng
2026-07-31 18:31:13 +08:00
parent 66575c6166
commit 89e5b7bed5
7 changed files with 2082 additions and 0 deletions
+177
View File
@@ -0,0 +1,177 @@
//! Tauri 命令:截图模块
//!
//! 命令清单:
//! - screenshot_capture_fullscreen:捕获虚拟屏并存入静态,返回元数据 + base64
//! - screenshot_take_fullscreen:取出并清除静态存储的全屏捕获
//! - screenshot_crop_stored:按物理像素裁剪已存储的全屏捕获
//! - screenshot_window_from_point:拾取指定屏幕坐标下的顶层窗口
//! - screenshot_enum_windows:枚举可见顶层窗口
//! - screenshot_capture_window:按 hwnd 捕获指定窗口
//! - screenshot_set_editor_image / screenshot_get_editor_image:编辑器图片传递
//! - screenshot_copy_image:写入剪贴板(CF_DIB
//! - screenshot_save_png:写入文件
use super::{CaptureData, WindowInfo};
/// 捕获整个虚拟屏(多显示器拼接),存入静态供后续裁剪,并返回 base64
#[tauri::command]
pub async fn screenshot_capture_fullscreen() -> Result<CaptureData, String> {
#[cfg(windows)]
{
// 屏幕捕获涉及 GDI 调用,放线程池避免阻塞 async 调度
let img = tauri::async_runtime::spawn_blocking(|| {
super::capture::capture_virtual_screen()
})
.await
.map_err(|e| format!("捕获任务失败: {}", e))??;
Ok(super::capture::store_fullscreen(img))
}
#[cfg(not(windows))]
{
Err("截图仅支持 Windows".into())
}
}
/// 取出并清除静态存储的全屏捕获(覆盖层取消时清理用)
#[tauri::command]
pub async fn screenshot_take_fullscreen() -> Result<Option<CaptureData>, String> {
#[cfg(windows)]
{
Ok(super::capture::take_fullscreen())
}
#[cfg(not(windows))]
{
Ok(None)
}
}
/// 按物理像素坐标裁剪已存储的全屏捕获
#[tauri::command]
pub async fn screenshot_crop_stored(
x: i32,
y: i32,
w: i32,
h: i32,
) -> Result<CaptureData, String> {
#[cfg(windows)]
{
tauri::async_runtime::spawn_blocking(move || {
super::capture::crop_stored(x, y, w, h)
})
.await
.map_err(|e| format!("裁剪任务失败: {}", e))?
}
#[cfg(not(windows))]
{
let _ = (x, y, w, h);
Err("截图仅支持 Windows".into())
}
}
/// 拾取指定物理屏幕坐标下的顶层窗口
#[tauri::command]
pub async fn screenshot_window_from_point(
x: i32,
y: i32,
) -> Result<Option<WindowInfo>, String> {
#[cfg(windows)]
{
tauri::async_runtime::spawn_blocking(move || {
Ok(super::capture::window_from_point(x, y))
})
.await
.map_err(|e| format!("查询失败: {}", e))?
}
#[cfg(not(windows))]
{
let _ = (x, y);
Ok(None)
}
}
/// 枚举所有可见顶层窗口
#[tauri::command]
pub async fn screenshot_enum_windows() -> Result<Vec<WindowInfo>, String> {
#[cfg(windows)]
{
tauri::async_runtime::spawn_blocking(|| super::capture::enum_visible_windows())
.await
.map_err(|e| format!("枚举失败: {}", e))
}
#[cfg(not(windows))]
{
Ok(vec![])
}
}
/// 按 hwnd 捕获指定窗口
#[tauri::command]
pub async fn screenshot_capture_window(hwnd: isize) -> Result<CaptureData, String> {
#[cfg(windows)]
{
tauri::async_runtime::spawn_blocking(move || {
let img = super::capture::capture_window(hwnd)?;
Ok(super::CaptureData {
png_base64: super::capture::base64_encode(&img.png),
width: img.width,
height: img.height,
})
})
.await
.map_err(|e| format!("捕获任务失败: {}", e))?
}
#[cfg(not(windows))]
{
let _ = hwnd;
Err("截图仅支持 Windows".into())
}
}
/// 存入编辑器图片(base64 PNG
#[tauri::command]
pub async fn screenshot_set_editor_image(png_base64: String) -> Result<(), String> {
super::set_editor_image(png_base64);
Ok(())
}
/// 取出编辑器图片(编辑器窗口加载时调用,取出即清除)
#[tauri::command]
pub async fn screenshot_get_editor_image() -> Result<Option<String>, String> {
Ok(super::take_editor_image())
}
/// 将 PNG base64 写入系统剪贴板(转 CF_DIB)
#[tauri::command]
pub async fn screenshot_copy_image(png_base64: String) -> Result<(), String> {
#[cfg(windows)]
{
tauri::async_runtime::spawn_blocking(move || {
super::capture::copy_png_to_clipboard(&png_base64)
})
.await
.map_err(|e| format!("剪贴板任务失败: {}", e))?
}
#[cfg(not(windows))]
{
let _ = png_base64;
Err("剪贴板仅支持 Windows".into())
}
}
/// 将 PNG base64 写入文件
#[tauri::command]
pub async fn screenshot_save_png(png_base64: String, path: String) -> Result<(), String> {
tauri::async_runtime::spawn_blocking(move || {
#[cfg(windows)]
{
super::capture::save_png_to_file(&png_base64, &path)
}
#[cfg(not(windows))]
{
let _ = (png_base64, path);
Err("文件写入仅支持 Windows".to_string())
}
})
.await
.map_err(|e| format!("保存任务失败: {}", e))?
}