Rust屏幕截图库xcap的使用,xcap提供跨平台屏幕捕获和图像处理功能

Rust屏幕截图库xcap的使用

XCap是一个用Rust编写的跨平台屏幕捕获库,支持Linux(X11, Wayland)、MacOS和Windows。XCap支持屏幕截图和视频录制功能(部分功能仍在开发中)。

功能特性

  • 跨平台支持: 可在Linux(X11, Wayland)、MacOS和Windows系统上运行
  • 多种截图模式: 支持全屏截图和窗口截图
  • 视频录制功能: 支持屏幕和窗口录制(部分功能仍在开发)

平台支持情况

功能 Linux(X11) Linux(Wayland) MacOS Windows(>=8.1)
屏幕捕获
窗口捕获
屏幕录制
窗口录制 🛠️ 🛠️ 🛠️ 🛠️

✅: 功能可用
⛔: 功能可用但可能有部分限制
🛠️: 开发中

完整示例代码

1. 屏幕捕获完整示例

use fs_extra::dir;
use std::time::Instant;
use xcap::Monitor;

// 处理文件名中的特殊字符
fn normalized(filename: String) -> String {
    filename.replace(['|', '\\', ':', '/'], "")
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 记录开始时间
    let start = Instant::now();
    
    // 获取所有显示器
    let monitors = Monitor::all()?;
    
    // 创建保存目录
    dir::create_all("screenshots", true)?;

    // 遍历所有显示器并截图
    for monitor in monitors {
        // 捕获当前显示器图像
        let image = monitor.capture_image()?;
        
        // 保存图像文件
        image.save(format!(
            "screenshots/monitor-{}.png",
            normalized(monitor.name()?)
        ))?;
    }

    // 输出运行耗时
    println!("截图完成,耗时: {:?}", start.elapsed());
    Ok(())
}

2. 窗口捕获完整示例

use fs_extra::dir;
use std::{time::Instant, path::Path};
use xcap::Window;

// 处理文件名特殊字符
fn sanitize_filename(filename: &str) -> String {
    filename.replace(['|', '\\', ':', '/', '*', '?', '"', '<', '>'], "")
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 确保输出目录存在
    let output_dir = "window_captures";
    if !Path::new(output_dir).exists() {
        dir::create_all(output_dir, true)?;
    }

    // 获取所有窗口
    let windows = Window::all()?;
    let start = Instant::now();

    // 遍历窗口并截图
    for (i, window) in windows.into_iter().enumerate() {
        // 跳过最小化窗口
        if window.is_minimized()? {
            continue;
        }

        // 获取窗口信息
        let title = window.title().unwrap_or_else(|_| "untitled".to_string());
        println!("正在捕获窗口 {}: {}", i, title);

        // 捕获窗口图像
        match window.capture_image() {
            Ok(image) => {
                // 保存图像文件
                let filename = format!(
                    "{}/window-{}-{}.png",
                    output_dir,
                    i,
                    sanitize_filename(&title)
                );
                image.save(filename)?;
            }
            Err(e) => eprintln!("无法捕获窗口 {}: {:?}", i, e),
        }
    }

    println!("窗口捕获完成,耗时: {:?}", start.elapsed());
    Ok(())
}

3. 屏幕录制完整示例

use std::{
    thread, 
    time::{Duration, Instant},
    path::Path,
    fs
};
use xcap::Monitor;
use image::ImageFormat;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 准备输出目录
    let output_dir = "screen_recordings";
    if !Path::new(output_dir).exists() {
        fs::create_dir(output_dir)?;
    }

    // 获取主显示器
    let monitor = Monitor::primary()?;
    println!("将在显示器 {} 上录制", monitor.name()?);

    // 创建录制器
    let (recorder, rx) = monitor.video_recorder()?;
    let recording_duration = Duration::from_secs(5);
    
    // 启动录制线程
    let handle = thread::spawn(move || {
        let mut frame_count = 0;
        let start_time = Instant::now();
        
        while let Ok(frame) = rx.recv() {
            // 保存帧为图像
            let filename = format!("{}/frame_{}.png", output_dir, frame_count);
            if let Err(e) = frame.save_with_format(filename, ImageFormat::Png) {
                eprintln!("保存帧 {} 失败: {:?}", frame_count, e);
            }
            frame_count += 1;
        }
        
        println!("录制线程结束,共捕获 {} 帧", frame_count);
        start_time.elapsed()
    });

    // 开始录制
    println!("开始录制...");
    recorder.start()?;
    thread::sleep(recording_duration);
    
    // 停止录制
    println!("停止录制...");
    recorder.stop()?;
    
    // 等待录制线程结束
    let elapsed = handle.join().unwrap();
    println!("实际录制时间: {:?}", elapsed);
    
    Ok(())
}

Linux系统依赖

在不同Linux发行版上需要安装以下依赖:

Debian/Ubuntu:

sudo apt-get install pkg-config libclang-dev libxcb1-dev libxrandr-dev libdbus-1-dev libpipewire-0.3-dev libwayland-dev libegl-dev

Alpine Linux:

sudo apk add pkgconf llvm19-dev clang19-dev libxcb-dev libxrandr-dev dbus-dev pipewire-dev wayland-dev mesa-dev

Arch Linux:

sudo pacman -S base-devel clang libxcb libxrandr dbus libpipewire

许可证信息

XCap库采用Apache License 2.0开源协议授权。


1 回复

Rust屏幕截图库xcap的使用指南

介绍

xcap是一个跨平台的Rust屏幕截图库,提供了简单的API来捕获屏幕内容并进行基本的图像处理。它支持Windows、macOS和Linux系统,能够捕获整个屏幕、特定窗口或屏幕的某个区域。

主要功能

  • 跨平台支持(Windows/macOS/Linux)
  • 获取屏幕信息(分辨率、名称等)
  • 捕获全屏、窗口或指定区域
  • 基本的图像处理功能
  • 支持多种图像格式输出

安装

在Cargo.toml中添加依赖:

[dependencies]
xcap = "0.9"

完整示例代码

use xcap::{Monitor, Window, Image};
use std::fs::File;
use image::imageops;

fn main() {
    // 示例1: 获取屏幕信息
    println!("=== 显示器信息 ===");
    let monitors = Monitor::all().unwrap();
    for monitor in monitors {
        println!(
            "显示器: {} 分辨率: {}x{}",
            monitor.name(),
            monitor.width(),
            monitor.height()
        );
    }

    // 示例2: 捕获主屏幕截图
    println!("\n=== 捕获主屏幕 ===");
    let primary_monitor = Monitor::primary().unwrap();
    let screenshot = primary_monitor.capture_image().unwrap();
    let mut file = File::create("primary_screen.png").unwrap();
    screenshot.save(&mut file, image::ImageOutputFormat::Png).unwrap();
    println!("主屏幕截图已保存为 primary_screen.png");

    // 示例3: 捕获特定窗口
    println!("\n=== 捕获特定窗口 ===");
    let windows = Window::all().unwrap();
    if let Some(window) = windows.iter().find(|w| w.title().contains("终端")) {
        let window_capture = window.capture_image().unwrap();
        let mut file = File::create("terminal_window.png").unwrap();
        window_capture.save(&mut file, image::ImageOutputFormat::Png).unwrap();
        println!("终端窗口截图已保存为 terminal_window.png");
    }

    // 示例4: 捕获并裁剪屏幕区域
    println!("\n=== 捕获屏幕区域 ===");
    let monitor = Monitor::primary().unwrap();
    let full_image = monitor.capture_image().unwrap();
    let cropped = full_image.crop(100, 100, 400, 300);
    let mut file = File::create("cropped_area.png").unwrap();
    cropped.save(&mut file, image::ImageOutputFormat::Png).unwrap();
    println!("裁剪区域截图已保存为 cropped_area.png");

    // 示例5: 图像处理
    println!("\n=== 图像处理 ===");
    let mut image = primary_monitor.capture_image().unwrap();
    // 转换为灰度图
    let gray_image = imageops::grayscale(&image);
    // 调整大小
    let resized = imageops::resize(&image, 800, 600, imageops::FilterType::Lanczos3);
    // 保存处理后的图像
    let mut gray_file = File::create("grayscale.png").unwrap();
    gray_image.save(&mut gray_file, image::ImageOutputFormat::Png).unwrap();
    let mut resized_file = File::create("resized.png").unwrap();
    resized.save(&mut resized_file, image::ImageOutputFormat::Png).unwrap();
    println!("灰度图已保存为 grayscale.png");
    println!("调整大小图已保存为 resized.png");

    // 示例6: 多显示器支持
    println!("\n=== 多显示器截图 ===");
    let all_monitors = Monitor::all().unwrap();
    for (i, monitor) in all_monitors.iter().enumerate() {
        let image = monitor.capture_image().unwrap();
        let mut file = File::create(format!("monitor_{}.png", i)).unwrap();
        image.save(&mut file, image::ImageOutputFormat::Png).unwrap();
        println!("显示器 {} 截图已保存为 monitor_{}.png", monitor.name(), i);
    }
}

注意事项

  1. 在Linux上可能需要安装额外的依赖:

    • Debian/Ubuntu: sudo apt install libx11-dev libxrandr-dev libxfixes-dev
    • Fedora: sudo dnf install libX11-devel libXrandr-devel libXfixes-devel
  2. 在某些系统上可能需要权限才能捕获某些窗口

  3. 捕获速度取决于屏幕分辨率和系统性能

xcap提供了简单直观的API来进行屏幕捕获操作,适合需要集成截图功能的Rust应用程序。

回到顶部