Imgtiger is an image viewer for the iTerm2 terminal emulator on OSX. I created imgtiger because the refrence-implementation image viewer, imgcat, was quite slow. I looked into it and found it was a shell script. Shell scripts are notoriously slow, so I thought it would be quite easy to create a faster version, and it was.
I started by reading the source code for imgcat to figure out how it worked. It's quite simple, iTerm2 has a custom escape code that can be used to display an image. The documentation for this escape code can be found here.
In short, the escape code follows this format:
\033]1337;File=[extra options]:<base64 encoded file contents>
Those extra options can be things like filename, size, width, height, and how to display the image.
In my upgraded version of imgcat I had two goals. One was to make imgcat but faster, and the second one was to make all the options from the escape code available. I added command flags that corrospond to each option in the escape code, and added much better help screen to explain the options.
As I was making imgtiger I found that the escape code was quite complex, so I split imgtiger into two parts, an API for the escape code and a CLI interface to the API. The imgtiger binary is just a CLI interface for the imgtiger API. Both are publicly available on crates.io.
During development I wanted to see how much I had improved upon imgcat, so I got an image of a tiger from flickr to use as a test. I also pulled a 4K render of an old blender project to serve as a large image transfer test.
Using hyperfine, an excelent CLI benchmarking tool, I measured the performance of both imgcat and imgtiger. Using the following command I tested both implementations.
hyperfine -w5 "<image_viewer> <test_image>"
With a 3000x2000 jpeg image, imgcat ran in 1.301s ± 0.007s. Imgtiger ran in 15.9ms ± 2.4ms with the same image. That's about an 80x speed up, acheiving my primary goal for this project.
The source code for imgtiger can be found here.