Last active
October 9, 2020 09:16
-
-
Save garfieldnate/d48f3efd47234dd8ee28d2e674cf8bbe to your computer and use it in GitHub Desktop.
Python 2/3 version of imgcat tool, which displays images inline in iTerm2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import print_function | |
import base64 | |
import os | |
import select | |
import sys | |
# tmux requires unrecognized OSC sequences to be wrapped with DCS tmux; | |
# <sequence> ST, and for all ESCs in <sequence> to be replaced with ESC ESC. It | |
# only accepts ESC backslash for ST. | |
def print_osc(terminal): | |
if terminal.startswith('screen'): | |
print_partial("\033Ptmux;\033\033]") | |
else: | |
print_partial("\033]") | |
# More of the tmux workaround described above. | |
def print_st(terminal): | |
if terminal.startswith('screen'): | |
print_partial("\a\033\\") | |
else: | |
print_partial("\a") | |
# print_image filename inline base64contents print_filename | |
# filename: Filename to convey to client | |
# inline: 0 or 1 | |
# base64contents: Base64-encoded contents | |
# print_filename: If non-empty, print the filename | |
# before outputting the image | |
def print_image(image_file_name=None, data=None): | |
terminal = os.environ.get('TERM') | |
print_osc(terminal) | |
print_partial('1337;File=') | |
args = [] | |
if image_file_name: | |
b64_file_name = base64.b64encode(image_file_name.encode('ascii')).decode('ascii') | |
args.append('name=' + b64_file_name) | |
with open(image_file_name, "rb") as image_file: | |
b64_data = base64.b64encode(image_file.read()).decode('ascii') | |
elif data: | |
b64_data = base64.b64encode(data).decode('ascii') | |
else: | |
raise ValueError("Expected image_file_name or data") | |
args.append('size=' + str(len(b64_data))) | |
args.append("inline=1") | |
print_partial(';'.join(args)) | |
print_partial(":") | |
print_partial(b64_data) | |
print_st(terminal) | |
def show_help(): | |
print("Usage: imgcat filename ...") | |
print(" or: cat filename | python imgcat.py -") | |
exit() | |
def print_partial(msg): | |
print(msg, end='') | |
def _read_binary_stdin(): | |
# see https://stackoverflow.com/a/38939320/474819 for other platform notes | |
PY3 = sys.version_info >= (3,0) | |
if PY3: | |
source = sys.stdin.buffer | |
else: | |
# Python 2 on Windows opens sys.stdin in text mode, and | |
# binary data that read from it becomes corrupted on \r\n | |
if sys.platform == "win32": | |
# set sys.stdin to binary mode | |
import msvcrt | |
msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY) | |
source = sys.stdin | |
return source.read() | |
def main(): | |
filename = None | |
data = None | |
if len(sys.argv) != 2: | |
show_help() | |
if sys.argv[1] != '-': | |
filename=sys.argv[1] | |
print_image(image_file_name=filename) | |
else: | |
data = _read_binary_stdin() | |
print_image(data=data) | |
if not filename and not data: | |
show_help() | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for this! I stumbled across it when trying to display images in iTerm2 from python, and it's working brilliantly for me.