atanunq / viuer

Rust library for displaying images in the terminal.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Sixel support

atanunq opened this issue · comments

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.

I saw the help wanted tag on atanunq/viu#16 . I am looking for tasks to test out code relay, and this sounds simple enough. I will create a task on code relay to implement this, and we'll see how it goes.

Ignore my last comment (I deleted it). I figured it out! I just have to test it on all the terminals that support sixel and then it's done.

Works on xterm, mlterm and others in Linux.
Can't get the sixel-sys cargo package to compile on either windows or mac. Not sure if it's a sixel-sys issue or a libsixel issue, either way I'll open an issue somewhere and look into it. If you want we could merge sixel support for linux under a cfg flag, or wait for windows and mac support.

Found the issue, and created an workaround for sixel-sys: AdnoC/sixel-sys#1 .
It hasn't been updated in 4 years, so not sure if the pull request will be accepted.
The bug is caused by a bug in the rust stdlib so it's possible that I could get it fixed in rust, so that we wouldn't have to pull in our own dependencies.

Thank you so much for the effort! I don't have time to look at it right now but will aim to do so during the weekend.

This is amazing! A lot of thought and effort has gone into it. Although, I am having troubles running it locally, I have a few comments:

  • It is okay if you test only one or two of the most popular sixel-supporting emulators. The list you have laid out looks like an overkill to me
  • adjust_offset and find_best_fit should be used to be able to 1. use the correct x and y offsets, 2. choose the right image size based on Config's width and height. Correct me if I am wrong, but I don't see how these are handled.
  • To add to the above, I think get_pixel_size can be removed and return the (w, h) from find_best_fit, see here.
  • Checking for sixel support can be massively simplified. First, I'd rather use higher-level API for capturing the response, see console::read_key. For example, we might want to read everything until the character c is read and check whether it contains either ;4; or ;4c. This will simplify both reading and parsing and we won't have to debug term_info bitmaps.

As you can see, I really think we should keep the logic as simple as possible and as platform-agnostic as possible. This project should be able to stand on top of the lower level crates that handle the multi-platform complexities for us.

I really appreciate your work on this issue. Also, I am more than happy to work on the above mentioned points myself. Can you open a PR on which we can collaborate so that I can push code, too?

Thank you again

Glad you like it!
It's not just me, I used coderelay.io. Code relay is a platform for contributors to do a small part of an issue and then hand it off (like a relay race, you run a small leg and then pass the baton to the next runner). So, all the code relay users contributed to this (which at this point in time, is mainly me and my friends, but we are growing!).

If you don't mind, it would really help us out if you put something like:

Made with coderelay.io

or

Coderelay.io contributed to this

At the top of the README.md, so we can attract more contributors, so we can work on more open source projects.

Also, as an open source maintainer yourself, feel free to submit tasks to code relay:
maintainer.

Fun fact: I made the code relay logo gif with viu, I drew the running guy in blender then converted it to a gif, played it with viu on https://github.com/Swordfish90/cool-retro-term then captured it with obs-studio. This is why I wanted to help contribute to this project and give back, so to speak.


On to the actual issue:

  1. Of those, Xterm is probably the most popular, which it did work on my PC. (When compiled to support it)
  2. Yeah, looks like those aren't handled at all. I think it's just printing at image resolution right now
  3. Probably, yeah.
  4. Just looking for ;4;, ;4c should work fine. I was running into an issue with the Device Attributes query: Xterm would print the response to the console (It was visible to the user) instead of to stdout. So, that's the source of the platform specific code, just getting it to print to stdout. I looked, but didn't see a way to do that with crossterm. Maybe we should open an issue on crossterm itself and see if we can find a cross platform way to get the device attributes.

I created a pull-request.

Fixed in #15, which contains some of the changes from #14.