summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorEmanuel Guevel <guevel.emanuel@gmail.com>2013-01-28 19:58:25 +0100
committerEmanuel Guevel <guevel.emanuel@gmail.com>2013-02-02 00:34:17 +0100
commit5795f388c6abe00538030ff597ee6ed69456ecec (patch)
tree2b5bb430adfe8dba62b80214ce9807c072c91745
parent3aa53556c3486c234edba7e4bc388d2c5ed29ccc (diff)
downloadranger-5795f388c6abe00538030ff597ee6ed69456ecec.tar.gz
ext: add img_display
This new file provides functions to draw images in the terminal.
-rw-r--r--ranger/ext/img_display.py79
1 files changed, 79 insertions, 0 deletions
diff --git a/ranger/ext/img_display.py b/ranger/ext/img_display.py
new file mode 100644
index 00000000..277d32ce
--- /dev/null
+++ b/ranger/ext/img_display.py
@@ -0,0 +1,79 @@
+# This software is distributed under the terms of the GNU GPL version 3.
+
+"""
+This module provides functions to draw images in the terminal using
+w3mimgdisplay, an utilitary program from w3m (a text-based web browser).
+w3mimgdisplay can display images either in virtual tty (using linux
+framebuffer) or in a Xorg session.
+
+w3m need to be installed for this to work.
+"""
+
+import termios, fcntl, struct, sys
+from subprocess import Popen, PIPE
+
+W3MIMGDISPLAY_PATH = '/usr/lib/w3m/w3mimgdisplay'
+
+def _get_font_dimensions():
+	"""
+	Get the height and width of a character displayed in the terminal in
+	pixels.
+	"""
+	s = struct.pack("HHHH", 0, 0, 0, 0)
+	fd_stdout = sys.stdout.fileno()
+	x = fcntl.ioctl(fd_stdout, termios.TIOCGWINSZ, s)
+	rows, cols, xpixels, ypixels = struct.unpack("HHHH", x)
+
+	return (xpixels // cols), (ypixels // rows)
+
+
+def _w3mimgdisplay(commands):
+	"""
+	Invoke w3mimgdisplay and send commands on its standard input.
+	"""
+	process = Popen(W3MIMGDISPLAY_PATH, stdin=PIPE, stdout=PIPE,
+			universal_newlines=True)
+
+	# wait for the external program to finish
+	output, _ = process.communicate(input=commands)
+
+	return output
+
+def draw(path, start_x, start_y, max_width, max_height):
+	"""
+	Draw an image file in the terminal.
+
+	start_x, start_y, max_height and max_width specify the drawing area.
+	They are expressed in number of characters.
+	"""
+	fontw, fonth = _get_font_dimensions()
+
+	max_width_pixels = max_width * fontw
+	max_height_pixels = max_height * fonth
+
+	# get image size
+	cmd = "5;{}".format(path)
+	output = _w3mimgdisplay(cmd).split()
+
+	if len(output) != 2:
+		raise Exception('Failed to execute w3mimgdisplay')
+
+	width = int(output[0])
+	height = int(output[1])
+
+	# get the maximum image size preserving ratio
+	if width > max_width_pixels:
+		height = (height * max_width_pixels) // width
+		width = max_width_pixels
+	if height > max_height_pixels:
+		width = (width * max_height_pixels) // height
+		height = max_height_pixels
+
+	# draw
+	cmd = "0;1;{x};{y};{w};{h};;;;;{filename}\n4;\n3;".format(
+			x = start_x * fontw,
+			y = start_y * fonth,
+			w = width,
+			h = height,
+			filename = path)
+	_w3mimgdisplay(cmd)
0' href='#n230'>230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267