It would be useful a feature (maybe activable with an option) to not stretch image on terminals supporting the image protocol.
For example the following code works for kitty:
diff --git a/Cargo.toml b/Cargo.toml
index 72bfd35..58da970 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -22,6 +22,7 @@ tempfile = "3.1"
console = { version = "0.15", default-features = false }
lazy_static = "1.4"
sixel-sys = { version = "0.3.1", optional = true }
+nix = {version = "0.25.0", default-feature = false, features = [ "ioctl" ]}
# avoid feature and crate name collision (thanks rabite0/hunter)
[dependencies.sixel-rs]
diff --git a/src/printer/kitty.rs b/src/printer/kitty.rs
index b950254..a2e2cfe 100644
--- a/src/printer/kitty.rs
+++ b/src/printer/kitty.rs
@@ -122,22 +122,48 @@ fn print_local(
img: &image::DynamicImage,
config: &Config,
) -> ViuResult<(u32, u32)> {
- let rgba = img.to_rgba8();
- let raw_img = rgba.as_raw();
- let path = store_in_tmp_file(raw_img)?;
-
adjust_offset(stdout, config)?;
// get the desired width and height
let (w, h) = find_best_fit(img, config.width, config.height);
+ use nix::ioctl_read_bad;
+ use nix::libc::{c_ushort, TIOCGWINSZ};
+
+ #[repr(C)]
+ #[derive(Default, Debug)]
+ pub struct TermSize {
+ rows: c_ushort,
+ columns: c_ushort,
+ x: c_ushort,
+ y: c_ushort,
+ }
+
+ ioctl_read_bad!(
+ /// Get terminal window size
+ tiocgwinsz,
+ TIOCGWINSZ,
+ TermSize
+ );
+
+ let mut tsize = TermSize::default();
+ unsafe { tiocgwinsz(0, &mut tsize as *mut _).expect("Cannot retrive kitty size") };
+
+ let img = img.resize(
+ (w as f64 * tsize.x as f64 / tsize.columns as f64) as u32,
+ (h as f64 * tsize.y as f64 / tsize.rows as f64) as u32,
+ image::imageops::FilterType::Triangle
+ );
+
+ let rgba = img.to_rgba8();
+ let raw_img = rgba.as_raw();
+ let path = store_in_tmp_file(raw_img)?;
+
write!(
stdout,
- "\x1b_Gf=32,s={},v={},c={},r={},a=T,t=t;{}\x1b\\",
+ "\x1b_Gf=32,s={},v={},a=T,t=t;{}\x1b\\",
img.width(),
img.height(),
- w,
- h,
base64::encode(path.to_str().ok_or_else(|| ViuError::Io(Error::new(
ErrorKind::Other,
"Could not convert path to &str"
Instead of telling kitty to stretch the image with the parameters c and r (number of columns and rows)of its graphics protocol, this code resizes the image (retaining aspect ratio) in a way it fits the desired number of rows and columns (bound width and height are computed multiplying the number of columns/rows by the ratio of size in pixel to the number of cells).
I attach an example to understand the importance of this feature: on the left the output of viu in kitty, on the right the output of the following code with the previous patch:
use viuer::{Config, print_from_file};
fn main() {
let conf = Config {
absolute_offset: false,
..Default::default()
};
print_from_file("sway.png", &conf).expect("Image printing failed.");
}
It can be seen how without this feature the image is unnaturally stretched; this is required for block printer, but easily avoidable for other printers.
Maybe there are also solutions better than the one I suggested.
It would be useful a feature (maybe activable with an option) to not stretch image on terminals supporting the image protocol.
For example the following code works for kitty:
Instead of telling kitty to stretch the image with the parameters c and r (number of columns and rows)of its graphics protocol, this code resizes the image (retaining aspect ratio) in a way it fits the desired number of rows and columns (bound width and height are computed multiplying the number of columns/rows by the ratio of size in pixel to the number of cells).
I attach an example to understand the importance of this feature: on the left the output of
viu
in kitty, on the right the output of the following code with the previous patch:It can be seen how without this feature the image is unnaturally stretched; this is required for block printer, but easily avoidable for other printers.
Maybe there are also solutions better than the one I suggested.