“Six-pixel” or “sixel” for short is a graphics format originating from DEC terminals. It is an 80s technology that went under the radar until it was revived the recent decade. Its data scheme is an escape sequence for terminals. Specifically, a sixel is a group of six pixels in a vertical column that represent bitmap data. The terminal processes sixel data as bits of information. Meaning that in order to view a sixel image file in a terminal with sixel support someone should do
cat image.six
A terminal emulator with sixel support is the de facto xterm
. It has
to be run by setting the terminal identifier to a sixel capable
terminal, such as VT340 which is noted in xterm’s
documentation on sixel graphics. The simplest way is using a
command-line argument.
xterm -ti vt340
Alternatively, add the following to ~/.Xresources
xterm*decTerminalID: vt340
When xterm has been configured to support sixel graphics, a number of
other resources have their values determined by decTerminalID
. This
leads to some limitations that have no reason to exist. Add
xterm*numColorRegisters: 256
xterm*sixelScrolling: 1
xterm*sixelScrollsRight: 1
and then merge the properties to the resource database with
xrdb -merge ~/.Xresources
Users running a Wayland compositor may prefer to use foot instead, a minimal sixel-capable Wayland-native terminal emulator. For macOS, the well known iTerm2 has sixel support since v3. For Windows, Mintty and there is an ongoing effort for adding support in Microsoft Terminal. The cross platform Alacritty is near ready.
Test it downloading the “snake” image in sixel format from libsixel project.
wget "https://raw.githubusercontent.com/saitoha/libsixel/master/images/snake.six"
cat snake.six
ImageMagick supports converting from and to sixel format. Based on that,
if ImageMagick is installed then the following simple script can be used
to show any image in terminal. The GEOMETRY
environmental variable and
the -g
argument (overrides the previous) can be used to change the
size of shown image.
~/bin/catix
#!/usr/bin/env bash
if [[ "$1" == "-g" ]]; then
GEOMETRY="$2"
shift 2
fi
for f in "$@"; do
convert "$f" -geometry ${GEOMETRY:=800x480} sixel:-
done
Test it downloading the “snake” image in png format from libsixel project.
wget "https://raw.githubusercontent.com/saitoha/libsixel/master/images/snake.png"
catix snake.png
A similar to this but more advanced, giving some more options, script is
sixcat. As it’s a script installation is simple. Just retrieve it,
make it executable and put it in a $PATH
directory. If it’s called as
sixgif
, it will play gif animations in the top left instead of
scrolling all the frames as multiple images.
wget "https://gist.githubusercontent.com/hackerb9/a96cea91e6122d09a6c97f5eb797d5fa/raw/6a030622bf34c2c3f79244023fabb30d44a68e16/sixcat"
sixcat snake.png
By the developer of the previous script, a useful tool building atop ImageMagick is lsix. Also a script and its installation is the same as before.
wget "https://github.com/hackerb9/lsix/raw/master/lsix"
lsix
As its description in project page says, it’s like ls
but for images.
Running it shows sixel-based thumbnails in terminal. When run without
arguments it shows thumbnails for every image in current directory.
When specific files are required those can be put as argument. If a gif
is specified, the frames will be expanded and shown as montage.
Recent gnuplot versions have sixel support. Basically
gnuplot right now has two implementations. The older sixel
terminal
uses built-in bitmap code, whereas the newer sixelgd
draws the
graphics using gdlib. Its advantages are “truecolor”,
truetype fonts, transparency, and anti-aliased lines. For an example run
gnuplot -e "set term sixelgd truec; test palette"
A number of Julia packages provide native sixel support, such as GR and of course Gaston, a front-end to gnuplot. Rather figuring out which do, the ImageMagick-based SixelTerm and libsixel-based TerminalGraphics can be used. For example using the former,
julia> using Plots, SixelTerm
julia> scatter(rand(100))
A library for writing programs outputting sixel graphics is, the
mentioned a few times already, libsixel. Thanks to libsixel, a number
of utilities now exist making use of this format. Those utilities can be
integrated to popular programs such as w3m and ranger, in order to
provide sixel graphics support. Installing it also gets someone the
img2sixel
tool which can be considered a more advanced version of the
two previous scripts. Specifically img2sixel
can decode and play
real-time gif animations.
wget "https://raw.githubusercontent.com/saitoha/libsixel/master/images/seq2gif.gif"
img2sixel seq2gif.gif
Beyond that, the project page has countless sixel examples. Some interesting ones are video streaming by using a patched ffmpeg, various applications by using a patched SDL (e.g. games, QEMU, and NetSurf), LaTeX output, and others.
Closing up, the kitty terminal has put forward its own graphics protocol. According to kitty’s developer Kovid, this protocol is simpler and solves some inherent issues in sixel scheme. The most essential being that this protocol isn’t an image format on its own but rather a way to display images. The approach is similar to what iTerm2 and Mintty have been doing alongside their sixel support, albeit with their own implementations instead. This also solves another issue, the lack of true color (24-bit) in sixel. The format supports RGB or HLS color (smaller color space; 16-bit) but terminal implementations may be limited to number of color registers. Sixel being palette-based means that for efficiency that number should be low (up to 256 colors).