Rust图像终端显示库viuer的使用,viuer提供高效终端图像渲染与ASCII艺术转换功能

Rust图像终端显示库viuer的使用

viuer是一个Rust库,可以轻松地在终端中显示图像。它具有简单的接口并通过单个结构进行配置。默认的打印方法是使用下半块字符(\u2585)。此外,它还支持一些自定义图形协议,可以在特定环境中显示全分辨率图像:

  • Kitty终端协议
  • iTerm终端协议
  • Sixel协议(需要启用sixel特性)

基本用法

使用默认特性时,只能打印image::DynamicImage类型的图像:

use viuer::{print, Config};

let conf = Config {
    // 从第4行第20列开始显示
    x: 20,
    y: 4,
    ..Default::default()
};

let img = image::DynamicImage::ImageRgba8(image::RgbaImage::new(20, 10));
print(&img, &conf).expect("Image printing failed.");

启用print-file特性后,viuer也可以直接处理文件:

use viuer::{print_from_file, Config};

let conf = Config {
    // 设置尺寸
    width: Some(80),
    height: Some(25),
    ..Default::default()
};

// 以80×25的终端单元格尺寸显示img.jpg
// 实际图像分辨率将是80×50,因为每个单元格包含两个像素
print_from_file("img.jpg", &conf).expect("Image printing failed.");

完整示例

下面是一个更完整的示例,展示如何使用viuer在终端显示图像:

use viuer::{print_from_file, Config};
use std::path::Path;
use image::io::Reader as ImageReader;
use image::DynamicImage;

fn main() {
    // 创建配置
    let conf = Config {
        // 设置显示位置
        x: 10,
        y: 5,
        // 设置显示宽度(以终端字符为单位)
        width: Some(60),
        // 设置显示高度(以终端字符为单位)
        height: Some(30),
        // 保持原始宽高比
        preserve_aspect_ratio: true,
        // 使用透明背景
        transparent: true,
        // 使用iTerm协议(如果支持)
        protocol: Some(viuer::Protocol::Iterm),
        // 其他配置保持默认
        ..Default::default()
    };

    // 图像文件路径
    let image_path = Path::new("example.jpg");

    // 检查文件是否存在
    if !image_path.exists() {
        eprintln!("错误: 图片文件不存在: {:?}", image_path);
        return;
    }

    // 方法1: 直接使用print_from_file
    if let Err(e) = print_from_file(image_path, &conf) {
        eprintln!("显示图片失败: {}", e);
    }

    // 方法2: 先加载图片再显示(提供更多控制)
    match ImageReader::open(image_path) {
        Ok(reader) => {
            match reader.decode() {
                Ok(img) => {
                    // 调整配置
                    let mut conf2 = conf;
                    conf2.width = Some(40); // 调整宽度
                    conf2.height = Some(20); // 调整高度
                    
                    // 打印图片
                    if let Err(e) = viuer::print(&img, &conf2) {
                        eprintln!("显示图片失败: {}", e);
                    }
                },
                Err(e) => eprintln!("解码图片失败: {}", e),
            }
        },
        Err(e) => eprintln!("打开图片失败: {}", e),
    }
}

文档

所有配置选项都可以在完整文档中找到。

viuer是一个MIT许可的开源项目,由Atanas Yankov(atanunq)维护。


1 回复

viuer: Rust图像终端显示与ASCII艺术转换库

介绍

viuer是一个Rust库,用于在终端中高效地显示图像和进行ASCII艺术转换。它提供了简单易用的API,可以将图像渲染到终端,支持多种输出格式和配置选项。

主要功能

  • 在终端中显示图像
  • 将图像转换为ASCII艺术
  • 支持多种图像格式
  • 可配置的输出选项(颜色、大小等)
  • 跨平台支持

安装

在Cargo.toml中添加依赖:

[dependencies]
viuer = "0.6"

基本使用方法

1. 在终端显示图像

use viuer::{print_from_file, Config};

fn main() {
    let config = Config {
        // 设置宽度为终端宽度的80%
        width: Some(80),
        // 保持宽高比
        preserve_aspect: true,
        // 使用真彩色
        truecolor: true,
        ..Default::default()
    };

    // 从文件显示图像
    print_from_file("example.jpg", &config).expect("Image printing failed");
}

2. 将图像转换为ASCII艺术

use viuer::{ascii_from_file, Config};

fn main() {
    let config = Config {
        width: Some(60),
        height: Some(30),
        // 使用ASCII字符代替颜色
        use_ascii: true,
        ..Default::default()
    };

    // 获取ASCII表示
    let ascii_art = ascii_from_file("example.png", &config).expect("Failed to create ASCII art");
    println!("{}", ascii_art);
}

3. 从内存中的图像数据渲染

use viuer::{print, Config};
use image::open;

fn main() {
    let img = open("example.jpg").expect("Failed to open image").to_rgb8();
    
    let config = Config {
        absolute_offset: false,
        x: 10,  // 水平偏移
        y: 5,   // 垂直偏移
        ..Default::default()
    };

    print(&img, &config).expect("Failed to print image");
}

高级配置选项

viuer的Config结构体提供了多种配置选项:

pub struct Config {
    /// 输出宽度(字符数)
    pub width: Option<u32>,
    /// 输出高度(字符数)
    pub height: Option<u32>,
    /// 是否保持宽高比
    pub preserve_aspect: bool,
    /// 水平偏移
    pub x: u32,
    /// 垂直偏移
    pub y: u32,
    /// 是否使用绝对坐标(否则相对于光标位置)
    pub absolute_offset: bool,
    /// 是否使用真彩色(24位色)
    pub truecolor: bool,
    /// 是否使用ASCII字符代替颜色块
    pub use_ascii: bool,
    /// 是否使用ANSI转义序列
    pub use_kitty: bool,
    /// 是否使用iTerm2协议
    pub use_iterm: bool,
    /// 是否恢复光标位置
    pub restore_cursor: bool,
}

使用示例:动态图像显示

use viuer::{print, Config};
use image::{DynamicImage, RgbImage};
use std::time::Duration;
use std::thread;

fn main() {
    // 创建一个简单的动画
    for i in 0..10 {
        // 创建一个渐变图像
        let mut img = RgbImage::new(100, 50);
        for x in 0..100 {
            for y in 0..50 {
                img.put_pixel(x, y, image::Rgb([x as u8, y as u8, (x + y + i * 10) as u8]));
            }
        }
        
        let config = Config {
            width: Some(50),
            height: Some(25),
            ..Default::default()
        };
        
        // 清除之前的输出
        print!("\x1B[2J\x1B[1;1H");
        
        // 打印新图像
        print(&DynamicImage::ImageRgb8(img), &config).unwrap();
        
        thread::sleep(Duration::from_millis(100));
    }
}

完整示例代码

下面是一个结合了viuer多个功能的完整示例,展示如何从文件加载图像、转换为ASCII艺术,并在终端中动态显示:

use viuer::{print_from_file, ascii_from_file, print, Config};
use image::{DynamicImage, RgbImage};
use std::time::Duration;
use std::thread;

fn main() {
    // 示例1:直接从文件显示图像
    println!("示例1:直接显示图像");
    let config1 = Config {
        width: Some(60),
        preserve_aspect: true,
        truecolor: true,
        ..Default::default()
    };
    print_from_file("example.jpg", &config1).expect("Failed to print image");
    
    thread::sleep(Duration::from_secs(2));
    
    // 示例2:转换为ASCII艺术
    println!("\n示例2:ASCII艺术");
    let config2 = Config {
        width: Some(60),
        height: Some(30),
        use_ascii: true,
        ..Default::default()
    };
    let ascii_art = ascii_from_file("example.jpg", &config2).expect("Failed to create ASCII art");
    println!("{}", ascii_art);
    
    thread::sleep(Duration::from_secs(2));
    
    // 示例3:动态图像显示
    println!("\n示例3:动态图像");
    for i in 0..10 {
        // 创建动态变化的图像
        let mut img = RgbImage::new(80, 40);
        for x in 0..80 {
            for y in 0..40 {
                let r = ((x as f32 * 3.2) as u8).wrapping_add(i * 5);
                let g = ((y as f32 * 6.4) as u8).wrapping_add(i * 3);
                let b = ((x as f32 + y as f32) as u8).wrapping_add(i * 10);
                img.put_pixel(x, y, image::Rgb([r, g, b]));
            }
        }
        
        let config3 = Config {
            width: Some(60),
            height: Some(30),
            truecolor: true,
            ..Default::default()
        };
        
        // 清除终端
        print!("\x1B[2J\x1B[1;1H");
        println!("动态图像帧: {}/10", i+1);
        
        // 显示图像
        print(&DynamicImage::ImageRgb8(img), &config3).unwrap();
        thread::sleep(Duration::from_millis(300));
    }
}

注意事项

  1. 确保终端支持真彩色或256色以获得最佳效果
  2. 某些终端模拟器可能需要特殊配置才能正确显示图像
  3. 对于大型图像,渲染可能需要一些时间

viuer是一个功能强大但易于使用的库,非常适合在终端应用程序中添加图像显示功能或创建ASCII艺术效果。

回到顶部