Skip to content

Instantly share code, notes, and snippets.

@lambdalisue
Created September 6, 2021 19:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lambdalisue/827c7fc8fb0db4fd808d7311943a49f7 to your computer and use it in GitHub Desktop.
Save lambdalisue/827c7fc8fb0db4fd808d7311943a49f7 to your computer and use it in GitHub Desktop.
Minimum SIXEL in Rust
use anyhow::{anyhow, Result};
use std::io::Write;
// MIT: Atanas Yankov <atanas.yankov98@gmail.com>
// https://github.com/atanunq/viuer/blob/3b99255f0d1586dd5b8cb1d409fa8515d9e77493/Cargo.toml#L10
// https://github.com/atanunq/viuer/blob/3b99255f0d1586dd5b8cb1d409fa8515d9e77493/src/printer/sixel.rs#L23
pub fn render_image(image: &image::DynamicImage) -> Result<()> {
let image = image.resize(128, 128, image::imageops::Nearest);
let encoder = sixel::encoder::Encoder::new()
.map_err(|e| anyhow!("failed to create a sixel encoder: {:?}", e))?;
let rgb = image.to_rgb8();
let frame = sixel::encoder::QuickFrameBuilder::new()
.width(rgb.width() as usize)
.height(rgb.height() as usize)
.format(sixel_sys::PixelFormat::RGB888)
.pixels(rgb.to_vec());
encoder
.encode_bytes(frame)
.map_err(|e| anyhow!("failed to encode bytes: {:?}", e))?;
Ok(())
}
// MIT: Atanas Yankov <atanas.yankov98@gmail.com>
// https://github.com/atanunq/viuer/blob/3b99255f0d1586dd5b8cb1d409fa8515d9e77493/Cargo.toml#L10
// https://github.com/atanunq/viuer/blob/3b99255f0d1586dd5b8cb1d409fa8515d9e77493/src/printer/sixel.rs#L82
pub fn is_sixel_supported() -> bool {
if let Ok(term) = std::env::var("TERM") {
match term.as_str() {
"mlterm" | "yaft-256color" | "foot" => return true,
"st-256color" | "xterm" | "xterm-256color" => {
return check_device_attrs().unwrap_or(false)
}
_ => {
if let Ok(term_program) = std::env::var("TERM_PROGRAM") {
return term_program == "MacTerm";
}
}
}
}
false
}
// MIT: Atanas Yankov <atanas.yankov98@gmail.com>
// https://github.com/atanunq/viuer/blob/3b99255f0d1586dd5b8cb1d409fa8515d9e77493/Cargo.toml#L10
// https://github.com/atanunq/viuer/blob/3b99255f0d1586dd5b8cb1d409fa8515d9e77493/src/printer/sixel.rs#L61
fn check_device_attrs() -> Result<bool> {
let mut term = console::Term::stdout();
let mut resp = String::new();
write!(&mut term, "\x1b[c")?;
term.flush()?;
while let Ok(c) = term.read_char() {
if c == 'c' {
break;
}
resp.push(c);
}
term.clear_line()?;
let mut bits = resp.split(";");
Ok(bits.any(|v| v == "4"))
}
@lambdalisue
Copy link
Author

  • sixel-rs
  • sixel-sys
  • console

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment