Giter Club home page Giter Club logo

viuer's People

Contributors

atanunq avatar bhansconnect avatar lilithium-hydride avatar nopdotcom avatar orhun avatar ram02z avatar rosekunkel avatar vaimer9 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

viuer's Issues

License issue

This crate depends on ansi_colours, which is licensed under the LGPL-3.0-or-later.
I think it's confusing that an MIT-licensed crate has copyleft dependency.

iTerm2 falls back to half-block printing inside tmux

Despite the fact that iTerm's image escape sequences and indeed its imgcat script seems to work inside tmux, viu will fall back to half-block rendering.

TERM_PROGRAM is equal to tmux inside tmux but exporting TERM_PROGRAM=iTerm.app manually doesn't seem to help either; this results in nothing being printed at all.

Is this something that was/can be considered inside viuer?

Edit:
quoting the imgcat script:

# tmux requires unrecognized OSC sequences to be wrapped with DCS tmux;
# <sequence> ST, and for all ESCs in <sequence> to be replaced with ESC ESC. It
# only accepts ESC backslash for ST. We use TERM instead of TMUX because TERM
# gets passed through ssh.
function print_osc() {
    if [[ $TERM == screen* ]]; then
        printf "\033Ptmux;\033\033]"
    else
        printf "\033]"
    fi
}

iTerm2 support

The modern MacOS terminal emulator iTerm2 natively supports high resolution images through a custom protocol. viuer could check if it is being invoked in iTerm and use this way of printing images instead of half-blocks.

To do that, the print method could be extended to check if the terminal is iTerm. The new printer would live in an iterm.rs file that has a iTermPrinter struct, implementing the Printer trait.

There is an unpublished rust crate that might be an inspiration, called iterm2.

Sixel support

Sixel graphics are a great way to display images in high resolution, given that the terminal supports it. libsixel has Rust bindings that could be used to bring the functionality to viuer, see on crates.io.

The way to go about it would be to check for sixel compatibility in the main print method. If that is the case, call SixelPrinter, which lives in sixel.rs and implements the Printer trait.

Just like with Kitty, rabite0's hunter has a sample implementation which could be extended.

iTerm2 printer is wrong aspect ratio due to manually passing in `width` and `height`

I posted this issue initially at: atanunq/viu#65

Comparing this source with imgcat's source makes it clear that the issue is viuer is attempting to manually calculate image size, which does not take into account iTerm2s specific line height/etc settings.

A simple fix to this is to simply not print width={};height={} when no width and height are specified, and allow iTerm2 to instead automatically calculate those.

I'm working on a PR right now for this.

Ueberzug support

Most of the terminals don't support kitty and iTerm protocols. For this reason, many applications(Including ranger) use ueberzug as a way to draw images into the terminal. While this way of displaying images is a bit hacky, it allows us to display full-color full resolution images in almost every common terminal emulator.

Add license

It looks like a license was never added when this was extracted from viu, which is under MIT. This should probably be rectified.

Terminology support

The Terminology terminal has its own custom protocol for displaying images from files. It is very straightforward to implement, the documentation is available in their README and I even wrote a C implementation for it.

(I started the imgt project before I found that viu exists, and now I've basically abandoned it. It would be nice to see a Terminology implementation here instead)

Oh, and Terminology also has the ability to send image files over SSH, but I never tested that. It might require some investigation.

Program hangs when displaying image with `use_kitty: true`

When setting the use_kitty: config option for viuer to true and attempting to display an image, the program will hang (seemingly indefinitely) and must be forcibly killed. No image is displayed. Setting this option to false allows everything to work as expected, albeit with blocks instead of a proper Kitty image. This is almost certainly a bug in my program, although I can't imagine what would cause such behavior and if anyone has any ideas I'd appreciate it :D

too many files under /tmp

I'm using viuer to display album cover. One use met a problem though, as in
tramhao/termusic#92 .
Would you please check if it's I'm using viuer wrong or you need to fix in upstream? Thanks so much.

Security issues when `sixel` feature is enabled

Currently, viuer suffers from the following security advisories:

$ cargo audit

Crate:     regex
Version:   0.1.80
Title:     Regexes with large repetitions on empty sub-expressions take a very long time to parse
Date:      2022-03-08
ID:        RUSTSEC-2022-0013
URL:       https://rustsec.org/advisories/RUSTSEC-2022-0013
Solution:  Upgrade to >=1.5.5
Dependency tree:
regex 0.1.80
└── semver-parser 0.6.2
    └── sixel 0.3.2
        └── viuer 0.6.1

Crate:     thread_local
Version:   0.2.7
Title:     Data race in `Iter` and `IterMut`
Date:      2022-01-23
ID:        RUSTSEC-2022-0006
URL:       https://rustsec.org/advisories/RUSTSEC-2022-0006
Solution:  Upgrade to >=1.1.4
Dependency tree:
thread_local 0.2.7
└── regex 0.1.80
    └── semver-parser 0.6.2
        └── sixel 0.3.2
            └── viuer 0.6.1

Both of these crates are reverse dependencies of the sixel crate which is outdated and unmaintained.

I looked at the codebase of sixel and realized these dependencies are not needed and removing them would fix these security issues. While I'm at it, I decided to maintain a fork of sixel since the maintainer is not that active on GitHub + they disabled issues on the repository.

That's why I created orhun/sixel-rs and I will be submitting a PR to switch to this crate. See the changelog here.

viuer with tui

I'm using viuer with tui-rs and instead of an image getting following:
image

Support for additional block characters

There are a number of block characters in Unicode:

  • Half blocks (U+2580, U+2584):
    ▀ | ▃
  • Quadrants (U+2596..U+259f):
    ▖ | ▗ | ▘ | ▙ | ▚ | ▛ | ▜ | ▝ | ▞ | ▟
  • Sextants (U+1fb00..U+1fb3b):
    🬀 | 🬁 | 🬂 | 🬃 | 🬄 | 🬅 | 🬆 | 🬇 | 🬈 | 🬉 | 🬊 | 🬋 | 🬌 | 🬍 | 🬎 | 🬏
    🬐 | 🬑 | 🬒 | 🬓 | 🬔 | 🬕 | 🬖 | 🬗 | 🬘 | 🬙 | 🬚 | 🬛 | 🬜 | 🬝 | 🬞 | 🬟
    🬠 | 🬡 | 🬢 | 🬣 | 🬤 | 🬥 | 🬦 | 🬧 | 🬨 | 🬩 | 🬪 | 🬫 | 🬬 | 🬭 | 🬮 | 🬯
    🬰 | 🬱 | 🬲 | 🬳 | 🬴 | 🬵 | 🬶 | 🬷 | 🬸 | 🬹 | 🬺 | 🬻

Viuer currently only supports half blocks. It would be nice if it could also use quadrants and sextants to show images in higher resolution at the expense of color accuracy.

support braille rendering

hi, i simply want to request for support of rendering colored braille characters.
this is primarily useful for users of st with the boxdraw patch, as braille is able to be renderered as pixels.
this will be a bit similar to the 'blocks' rendering, but using braille characters.

[Feature Request] Un-viuer? Delete images

I'm trying to use the library for a terminal game, but I've come across a few snags against using it, such as #44. But since I'm controlling the screen instead of just outputting things, I also need the ability to delete images displayed using the kitty protocol.

Do not stretch image in terminals supporting graphics protocol

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.");
}

image

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.

Printing broken when in raw mode

When placing the terminal into raw mode (through Termion, etc.), each pair of rows will shift over such that the start of every new row is the x offset away from the previous row's end, resembling a stair pattern. From what I can see on the outside, it looks like it's just using a line break and expecting that it will also be properly returned to the beginning of the line after, which would not be the case in raw mode. I'm not experienced in Rust enough to personally confirm this, though. It'd be helpful if this behavior could be altered, perhaps through the Config struct.

How to clear the image printed?

Firstly, thanks for your work and it provides very good display result in kitty.
I'm using it in my repo(https://github.com/tramhao/termusic) to display the album photo.
The display works without problems. However, i need to clear the printed image if the song doesn't have an album photo.
I cannot figure out how to do it.
Thanks so much.

How to load image from bytes (include_bytes)?

I want to bundle my images with executable.
This is the code I used and it fails compilation with error

expected enum `image::dynimage::DynamicImage`, found array `[u8; 23307]
use viuer::{Config, print_from_file, print};
let conf = Config {
  transparent: true,
  absolute_offset: false,
  ..Default::default()
};
let img = include_bytes!("image.png");
print(img, &conf);

How could I convert bytes to DynamicImage?

feature request: get String from Read trait

In my opinion, your lib would benefit from a method like the following

pub fn image_to_string<R: Read>(from: R) -> Result<String, ViuError>

Disclosure:
I am interested in using this lib for tests of library https://crates.io/crates/bmp-monochrome
The library had a bug RCasatta/bmp-monochrome#2 that wasn't catch because it was on both encode and decode method, so I thought the only way to catch this kind of bug is introducing external image library in tests.

Images with transparency leak the transparency color into the borders even with 0 opacity.

For instance (you need to pip install pillow to run this):

#! /usr/bin/env python3

from PIL import Image
import subprocess, io, os

solid = Image.new('RGBA', (50,50), (0, 0, 0, 255))
t_red = Image.new('RGBA', (50,50), (255, 0, 0, 0))

combined = Image.new('RGBA', (100, 50))
combined.paste(solid, box=(0,0))
combined.paste(t_red, box=(solid.size[0],0))

with io.BytesIO() as f:
    combined.save(f, format='png')
    subprocess.run(['viu', '-t', '-'], input=f.getbuffer())
#if the terminal is small enough that the combined image fills the width this will show the border
size = os.get_terminal_size()
print('*'*int(size[0]/2))

I believe this is a of by one bug in printing transparent pixels. Sometimes the border appears 'darker' depending on size, and that's interpolation (probably on a odd total width and a small enough terminal width), but the red must not be interpolation because with a small enough terminal, the midpoint of the terminal width coincides with the last star, and with the end of the first image, and those stars stop before the red line.

FWIW chafa when it needs to 'interpolate' doesn't print a darker red line, but it does print some odd spikes ('-') at the border. Your solution is better +/- this bug.

This is on a terminal without kitty protocol or sixel support of course.

print_from_file should take AsRef<Path>, not &str

Currently, if you want to pass a Path to viuer::print_from_file, you have to convert it to a &str:

let path = Path::new("some/path/foo.png");
print_from_file(path.to_str().unwrap(), &Default::default());

This isn't very ergonomic, and if your path contains invalid UTF-8, you can't use it all. Since image::io::Reader::open already takes an AsRef<Path>, I don't see any technical reason for this limitation. Additionally, str already implements AsRef<Path>, so I don't think this would be a breaking change. I'm happy to submit a pull request implementing this change, if it's wanted.

I'd love a python wheel in pypi

Yeah, i know it sounds entitled. I suppose this can be done with maturin but i'm not one to do it, i don't know rust well and ffi is supposed to be harder.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.