#!/bin/bash -e ## tiv: Image viewer for Linux terminal ## # Character dimensions # For XTerm (W×H; change with L-Ctrl + RMB): # Huge: 10×20 # Large: 9×18 # Medium: 8×13 # Small: 7×14 # * Default: 6×13 # Tiny: 5×8 (recommended) # Unreadable: 1×2 (high resolution, slowest rendering, without double horizontal resolution) char_w=5 char_h=8 char_w=1 char_h=2 # If file doesn't exist, then die with 'No such file or directory' exit code if [ ! -f "$1" ] then exit 2 elif grep -q image <<<$(file "$1"); then # If file is image… cols_no=$(($(tput cols)*6)) lines_no=$(tput lines) window_w=$((cols_no*char_w)) window_h=$((lines_no*char_h)) img_dims=$(identify -format '%w %h' "$1") img_w=$(awk '{print $1}' <<<$img_dims) img_h=$(awk '{print $2}' <<<$img_dims) char_asp_r="($char_w/$char_h)" # Zoom parameter; you can use decimal comma case "$2" in "") zoom=100;; *) zoom=$(sed -e 's/,/./' <<<$2);; esac # Determine whether the image is landscape or portrait (or square) to ensure the image adapts to window/screen if [ $((img_w*window_h)) -gt $((img_h*window_w/6)) ] then out_v=$(bc -l <<<"scale=6; $cols_no/$img_w*$zoom*$char_asp_r/6") else out_v=$(bc -l <<<"scale=6; $lines_no/$img_h*$zoom") fi # MAIN ENGINE # printf "\e[;f" = move cursor to top left corner and further: # * Remove comment (if any) # * Use first frame from animated image (eg GIF) # * Convert to 8-bit depth # * Use Lanczos' (sharp but without distortions) interpolation filter, resize image to fit to the window # * Center image, fill empty spaces with black # * Export to ASCII PPM image file format and send to pipe, where: # * Remove the PPM header # * Align output to $cols_no columns (window width*6 [R G B r g b - FOREGROUND/background]) # * Convert 'R G B r g b' decimal values to ANSI escape code for set foreground/background color of the '▌' character # … and print formatted output to STDOUT (or file) # Reset formatting and move cursor to the top left corner printf "\e[;f$(convert -comment "" "$1"[0] -depth 8 -filter Lanczos2 -resize $(bc -l <<<"scale=6; $out_v/$char_asp_r*2")%x${out_v}\ -background black -gravity center -extent $((cols_no/3))x${lines_no}$3 -compress none ppm:- |\ tail -n+5 | xargs -n $cols_no |\ sed -e 's:$: :g;s:\([0-9]\+\) \([0-9]\+\) \([0-9]\+\) \([0-9]\+\) \([0-9]\+\) \([0-9]\+\) :\\e\[38;2;\1;\2;\3;48;2;\4;\5;\6m▌:g')\e[m\e[;f" # If file is not an image, then exit with 'Wrong medium type' exit code else exit 124 fi