Rust插件库twenty-twenty的使用:高效图像处理与视觉增强工具

Rust插件库twenty-twenty的使用:高效图像处理与视觉增强工具

twenty-twenty是一个用于视觉回归测试的Rust库,支持H.264帧(需启用h264功能)和普通图像比较。它使用SSIM(结构相似性)算法来量化图像差异,评分范围为0到1,1表示完全相同。

核心功能

  • 图像相似度比较
  • H.264帧比较(需启用h264功能)
  • 测试失败时自动生成差异报告
  • 支持参考图像自动更新

完整使用示例

// Cargo.toml 添加依赖
// twenty-twenty = "0.8.2"
// image = "0.24"  // 用于图像处理

use image::DynamicImage;
use std::path::Path;

fn main() {
    // 示例1: 比较生成的图像与参考图像
    compare_images();
    
    // 示例2: 比较H.264视频帧(需启用h264功能)
    compare_h264_frames();
}

fn compare_images() {
    // 生成测试图像 - 这里创建一个简单的红色正方形
    let mut img = image::RgbImage::new(100, 100);
    for pixel in img.pixels_mut() {
        *pixel = image::Rgb([255, 0, 0]); // 红色
    }
    let test_image = DynamicImage::ImageRgb8(img);
    
    // 与参考图像比较(相似度阈值设为0.85)
    twenty_twenty::assert_image("tests/reference_red_square.png", &test_image, 0.85);
}

fn compare_h264_frames() {
    // 模拟获取H.264帧数据
    let frame_data = simulate_h264_frame();
    
    // 与参考帧比较(相似度阈值设为0.9)
    twenty_twenty::assert_h264_frame("tests/reference_frame.h264", &frame_data, 0.9);
}

fn simulate_h264_frame() -> Vec<u8> {
    // 实际使用时应从视频源获取真实帧数据
    // 这里返回模拟数据
    vec![0x00, 0x00, 0x01, 0x67, /* 更多H.264 NALU数据... */]
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_ui_rendering() {
        // 模拟UI渲染输出
        let rendered_ui = render_test_ui();
        
        // 验证UI渲染结果
        twenty_twenty::assert_image("tests/ui_reference.png", &rendered_ui, 0.95);
    }
    
    fn render_test_ui() -> image::DynamicImage {
        // 实际项目中这里会包含UI渲染逻辑
        image::open("tests/test_ui.png").unwrap()
    }
}

关键功能说明

  1. 图像比较:

    twenty_twenty::assert_image(reference_path, &actual_image, min_similarity);
    
  2. H.264帧比较:

    twenty_twenty::assert_h264_frame(reference_path, &frame_data, min_similarity);
    
  3. 更新参考图像:

    TWENTY_TWENTY=overwrite cargo test test_ui_rendering
    
  4. CI集成:

    TWENTY_TWENTY=store-artifact-on-mismatch cargo test
    

实际应用场景

  1. UI测试: 验证UI渲染结果是否符合预期
  2. 图像处理: 确保图像处理算法输出保持一致
  3. 视频处理: 验证视频帧处理结果
  4. 可视化测试: 图表、图形等可视化输出验证

使用twenty-twenty可以显著简化视觉回归测试流程,确保图形输出的质量一致性。


1 回复

twenty-twenty: Rust中的高效图像处理与视觉增强工具

twenty-twenty是一个Rust编写的图像处理和视觉增强库,专注于提供高性能的图像比较和差异可视化功能。

主要特性

  • 高效的图像差异计算
  • 视觉增强的差异显示
  • 支持多种图像格式
  • 可定制的比较参数
  • 零成本抽象带来的高性能

安装

在Cargo.toml中添加依赖:

[dependencies]
twenty_twenty = "0.3"
image = "0.24"  # 需要image库来加载图像

完整示例代码

use image::GenericImageView;
use twenty_twenty::{Compare, Visualization};

fn main() {
    // 示例1: 基本图像比较
    basic_comparison();
    
    // 示例2: 带参数的自定义比较
    custom_comparison();
    
    // 示例3: 批量比较目录中的图像
    batch_comparison("images");
}

/// 基本图像比较示例
fn basic_comparison() {
    // 加载两幅测试图像
    let image1 = image::open("test1.png").unwrap().to_rgba8();
    let image2 = image::open("test2.png").unwrap().to_rgba8();
    
    // 使用默认参数比较图像
    let result = twenty_twenty::compare(&image1, &image2, Visualization::Diff);
    
    // 保存差异图像
    result.save("basic_diff.png").unwrap();
    println!("基本比较完成,结果保存为 basic_diff.png");
}

/// 自定义比较参数示例
fn custom_comparison() {
    let image1 = image::open("ui_screenshot.png").unwrap().to_rgba8();
    let image2 = image::open("ui_reference.png").unwrap().to_rgba8();
    
    // 创建自定义比较
    let comparison = Compare::new(&image1, &image2)
        .ignore_alpha()  // 忽略alpha通道
        .threshold(0.05) // 设置差异阈值
        .visualization(Visualization::SideBySide {
            alignment: twenty_twenty::Alignment::Center,
            spacing: 20,
            background: [240, 240, 240, 255], // 浅灰色背景
        })
        .compare();
    
    // 保存比较结果
    comparison.save("custom_comparison.png").unwrap();
    
    // 获取并打印差异指标
    let metrics = Compare::new(&image1, &image2)
        .ignore_alpha()
        .compare_metrics();
    
    println!("自定义比较结果:");
    println!("差异百分比: {:.4}%", metrics.diff_percentage * 100.0);
    println!("平均差异: {:.2}", metrics.mean_diff);
    println!("最大差异: {}", metrics.max_diff);
}

/// 批量比较目录中的图像
fn batch_comparison(dir: &str) {
    use std::path::Path;
    use twenty_twenty::{compare, Visualization};
    
    let dir_path = Path::new(dir);
    if !dir_path.exists() {
        println!("目录 {} 不存在", dir);
        return;
    }
    
    println!("开始在目录 {} 中批量比较图像...", dir);
    
    for entry in dir_path.read_dir().unwrap() {
        let entry = entry.unwrap();
        if entry.file_type().unwrap().is_file() {
            let path = entry.path();
            if let Some(ext) = path.extension() {
                if ext == "png" && !path.to_string_lossy().contains("reference") {
                    let base_name = path.file_stem().unwrap().to_string_lossy();
                    
                    // 查找对应的参考图像
                    let reference_path = path.with_file_name(format!("{}_reference.png", base_name));
                    
                    if reference_path.exists() {
                        println!("比较: {} 和 {}", path.display(), reference_path.display());
                        
                        let image = image::open(&path).unwrap().to_rgba8();
                        let reference = image::open(&reference_path).unwrap().to_rgba8();
                        
                        let result = compare(&image, &reference, Visualization::Diff);
                        let output_path = path.with_file_name(format!("{}_diff.png", base_name));
                        result.save(&output_path).unwrap();
                        
                        println!("差异结果保存为: {}", output_path.display());
                    }
                }
            }
        }
    }
    
    println!("批量比较完成");
}

代码说明

  1. 基本比较:

    • 使用twenty_twenty::compare函数进行最简单的图像比较
    • 生成标准差异图像并保存
  2. 自定义比较:

    • 使用Compare构建器模式自定义比较参数
    • 设置忽略alpha通道、差异阈值等
    • 生成并排比较视图
    • 获取详细的差异指标数据
  3. 批量处理:

    • 扫描目录中的PNG文件
    • 自动查找对应的参考图像(以"_reference.png"结尾)
    • 为每对图像生成差异图
    • 保存差异结果为"原文件名_diff.png"

使用建议

  1. 对于UI测试,建议阈值设为0.01-0.05之间
  2. 处理大量图像时,考虑使用多线程并行处理
  3. 对于持续集成环境,可以将差异百分比作为测试通过/失败的标准

这个示例展示了twenty-twenty库的核心功能,包括基本比较、自定义参数比较和批量处理能力。您可以根据实际需求调整参数和可视化方式。

回到顶部