24 comments

[ 0.24 ms ] story [ 33.8 ms ] thread
What I was surprised to learn when trying to set one of these up to use over SSH[0] - this image rendering is not "in the terminal" (in retrospect, it perhaps obviously can't be). These tools draw directly onto the X11 canvas, which for me begs the question - what are they for? If you want a real GUI that badly, why not use one that's not in the terminal?

Ncurses-style CLIs have the benefit of being usable over bad connections and on headless boxes. I can't see why you would want to display an image in your terminal if you're already running a graphical session, and presumably have an image viewer installed.

[0]: turns out there are programs which turn images into blocks of coloured characters, and therefore do work over SSH.

I think once you've been "living" in your terminal for a while you're pretty used to the keyboard-centric life and going to a separate mouse-centric window manager world can be considered to be cumbersome.

That said, I do agree with you. I also think any image viewing functionality needs to have a practical way to get that image sent through the same channel as that terminal connection itself so that if you're on it remotely it will still work...

What this is doing is basically displaying an image, independently of your terminal, and keeping it in sync as you move the window, therefore won't work over SSH.

As what they are for, I use ueberzug and something like entr (tool that watches a file for changes) to display the output of programs that generate images, without having to either open the image manually or open a new image viewer through scripting. Another use I had for it was to visualize a syntax tree of an expression when I was writing a compiler, to ensure everything made sense in a more visual way. I don't know if it has any use for sysadmin tasks, to be honest, but for my hobby programming projects it's rather useful.

As you note at the end there are tools to do the blocks thing, like Sixel (it's mentioned elsewhere in this news' comments) but you will need to watch out for size and colors. Representing a large, complex image over sixels is a bit meh, but for smaller ones like say 160x144 it should work.

A more practical and cohesive alternative is Sixel [https://saitoha.github.io/libsixel/], which is an in-band, escape based image format supported by “modern” terminal emulators, like iTerm2, which also has a proprietary image format [https://iterm2.com/documentation-images.html]

I prefer in-band images because it doesn’t require complex coordination between the process that wants to display the image and other software like X11, instead the process just writes out the appropriate bytes to the TTY and they get displayed.

Sixel is really useful, but it is not optimal in terms of color quantization and fast rendering (it is quite a pain to write a color sixel image). The world needs a hero that submits simultaneously a patch to xterm, iterm and all widely used terminals to accept decent in-band color images--using verbatim framebuffers with a tiny header.
If you need verbatim frame buffers, VNC is good for that. Basically, you will need to integrate VNC protocol into terminal protocol.
(comment deleted)
Why stop at images? If you go the full way and include drawing commands like those in cairo script (https://cairographics.org/manual/cairo-Script-Surfaces.html) you can essentially abolish any other sort of app besides the terminal. Your GUI is then simply created by writing to stdout.
> ... simply created by writing to stdout.

Shut up and take my money!

No, really, that would be awesomely cool. Having support for in-band inline images is a useful start yet. I'm not the hero the world needs, but if I had a lot of money I would surely pay proficient hackers to write that thing.

I think once you add the user input side, you've reinvented something not unlike X-as-it-originally was, though.
> you've reinvented something not unlike X-as-it-originally was

Sounds good to me. Technology advances by the continued reinvention of the wheel, that offers new opportunities for simplification and improvement at each iteration.

I really want to like Sixel but it's such a horrible encoding, both in terms of specification and overall image quality. I much prefer the proprietary escape sequences that base 64 encode PNG (or similar) data. Granted the base 64 encoding will add ~30% to the image size in transit but modern image formats are compressed these days (which Sixel is not) so it's not a complete loss. Plus PNG will produce better quality images.

It's just a pity there isn't even a de facto standard for how to escape base 64 encoded image files. There's only 3 terminal emulators that I know of which support in-band images (Sixel aside): Kitty (not to be confused with KiTTY, a PuTTY fork), iTerm2 and Terminology. All of which have their own escape sequences.

I'd built a little script which opened an image in the terminal, irrespective of which terminal emulator you ran it would render the image in the best available format (falling back to ANSI block art if nothing better was available). It was a nightmare to write because of all the different terminals doing their own things. And when this stuff doesn't work there's no clue why because in-band escape sequences aren't something that produces an error if you get something wrong. It either works or it doesn't. Then you have multiplexers like tmux that can add their own undefined behaviour to proceedings.

As CLI tools go by, that was probably one of my most frustrating exercises for the least reward (I could probably count on one hand the number of times I've actually needed that script).

Back in the old days, you could open a graphics screen on most home computers. E.g. in Applesoft BASIC, you could use HGR and PLOT commands to draw things. That simplicity is missing on modern computers.
That's true. I remember the Atari 8-bit had the same thing, some modes having a text bottom and a graphical top where plot and such could be used.
You could do that pretty easily with SciPy and PyPlot. Of course not as easily as a dedicated command, but it's pretty nice either way.

I use it all the time to plot the waveform of audio files before I listen to them.

Framebuffer and fim as the image viewer. Done.
> no race conditions as a new window is created to display images

That is NOT drawing images on terminals. It’s just embedding an image viewer into the terminal window.

This will not work over SSH.

> Draw images in terminals

No image giving me a preview in the readme. I don’t know how people seem to always ignore the most important part somehow.