-
Notifications
You must be signed in to change notification settings - Fork 894
Image Previews
Since 1.6.0, ranger can preview images in full color. This works by calling a program named w3mimgdisplay
that's included in the w3m web browser, which draws images directly into the terminal.
If you use iTerm2, a Mac OS X terminal replacement, you can enable a method that takes advantage of the built-in drawing functionality so you won't need w3m.
Steps to enable it:
- Get a compatible terminal. Terminals that are known to work are rxvt-unicode, xterm and st (at least since st 0.6, besides if it doesn't work under st, you maybe use ueberzug).
- install w3m with the image drawing feature. On Arch Linux, the package is called "w3m", on Debian and Fedora it's "w3m-img".
- Add the line
set preview_images true
to your~/.config/ranger/rc.conf
. - In the most recent versions, you no longer need to get the
scope.sh
configuration file by runningranger --copy-config=scope
, however if you do you can edit it to get graphical previews ofpdf
s andsvg
s for example. - Restart ranger and navigate to an image file. \o/
The original python version of ueberzug has been discontinued but an active fork rewrriten in c++ is available and works as a drop-in replacement.
-
This will work with most terminals and even with tmux. Doesn't work well with tabs.
-
Install ueberzugpp or on Arch Linux it is also available in the AUR.
-
Add the following lines to your
~/.config/ranger/rc.conf
.set preview_images true set preview_images_method ueberzug
-
Restart ranger and navigate to an image file. \o/
The image preview methods urxvt
and urxvt_full
can be used with the urxvt terminal and are typically more reliable. They use a special escape sequence to change the background of the terminal in order to render the image.
- Run urxvt with pixbuf support (some operating systems ship it without pixbuf support, but for example ArchLinux has an AUR package called
rxvt-unicode-pixbuf
which should work) - Add the following lines to your
~/.config/ranger/rc.conf
:You can also chooseset preview_images true set preview_images_method urxvt
urxvt-full
if you would like the image to fill the whole terminal rather than just the preview pane. - Restart ranger and navigate to an image file. \o/
NOTE: You need at least iTerm2 version 2.9 for the image preview feature to work.
- Add the following lines to your
~/.config/ranger/rc.conf
:set preview_images true set preview_images_method iterm2
- Restart ranger and navigate to an image file. \o/
The image preview method kitty
can be used with the kitty terminal.
NOTE: Tested with kitty 0.14.6
- Add the following lines to your
~/.config/ranger/rc.conf
:set preview_images true set preview_images_method kitty
- Restart ranger and navigate to an image file. \o/
NOTE: You need at least mpv version 0.25 for the below method to work.
The mpv image preview method allows ranger to control an external client for viewing media. The benefit of this approach is that both images and videos share a single, separate window.
- Add the following lines to your
~/.config/ranger/commands.py
:
import subprocess
import json
import atexit
import socket
from pathlib import Path
import logging
logger = logging.getLogger(__name__)
import traceback
from ranger.ext.img_display import ImageDisplayer, register_image_displayer
@register_image_displayer("mpv")
class MPVImageDisplayer(ImageDisplayer):
"""Implementation of ImageDisplayer using mpv, a general media viewer.
Opens media in a separate X window.
mpv 0.25+ needs to be installed for this to work.
"""
def _send_command(self, path, sock):
message = '{"command": ["raw","loadfile",%s]}\n' % json.dumps(path)
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect(str(sock))
logger.info('-> ' + message)
s.send(message.encode())
message = s.recv(1024).decode()
logger.info('<- ' + message)
def _launch_mpv(self, path, sock):
proc = subprocess.Popen([
* os.environ.get("MPV", "mpv").split(),
"--no-terminal",
"--force-window",
"--input-ipc-server=" + str(sock),
"--image-display-duration=inf",
"--loop-file=inf",
"--no-osc",
"--no-input-default-bindings",
"--keep-open",
"--idle",
"--",
path,
])
@atexit.register
def cleanup():
proc.terminate()
sock.unlink()
def draw(self, path, start_x, start_y, width, height):
path = os.path.abspath(path)
cache = Path(os.environ.get("XDG_CACHE_HOME", "~/.cache")).expanduser()
cache = cache / "ranger"
cache.mkdir(exist_ok=True)
sock = cache / "mpv.sock"
try:
self._send_command(path, sock)
except (ConnectionRefusedError, FileNotFoundError):
logger.info('LAUNCHING ' + path)
self._launch_mpv(path, sock)
except Exception as e:
logger.exception(traceback.format_exc())
sys.exit(1)
logger.info('SUCCESS')
- Ensure the following lines appear in your
~/.config/ranger/rc.conf
:
set preview_images true
set preview_images_method mpv
set use_preview_script true
set preview_script ~/path/to/your/scope.sh # or whatever your preview script is
- Restart ranger and navigate to an image file. \o/
If you want mpv to support common image viewing features, see this gist for a sample mpv configuration.
Source: guyuming76@83a7264 from #2628
- Add the following to your
~/.config/ranger/commands.py
:
from ranger.ext.img_display import ImageDisplayer, register_image_displayer
from subprocess import Popen, PIPE, run
import time
@register_image_displayer("imv")
class IMVImageDisplayer(ImageDisplayer):
"""
Implementation of ImageDisplayer using imv
"""
is_initialized = False
def __init__(self):
self.process = None
def initialize(self):
""" start imv """
if (self.is_initialized and self.process.poll() is None and
not self.process.stdin.closed):
return
self.process = Popen(['imv'], cwd=self.working_dir,
stdin=PIPE, universal_newlines=True)
self.is_initialized = True
time.sleep(1)
def draw(self, path, start_x, start_y, width, height):
self.initialize()
run(['imv-msg', str(self.process.pid), 'close'])
run(['imv-msg', str(self.process.pid), 'open', path])
def clear(self, start_x, start_y, width, height):
self.initialize()
run(['imv-msg', str(self.process.pid), 'close'])
def quit(self):
if self.is_initialized and self.process.poll() is None:
self.process.terminate()
- Ensure the following lines appear in your
~/.config/ranger/rc.conf
:
set preview_images true
set preview_images_method imv
set use_preview_script true
set preview_script ~/path/to/your/scope.sh # or whatever your preview script is
- Restart ranger and navigate to an image file. \o/
Image display methods can be added via ~/.config/ranger/commands.py
by implementing ImageDisplayer.draw()
and registering your class with a nickname to be used with set preview_images_method
. So basically:
- Add the following lines to your
~/.config/ranger/commands.py
:
from ranger.ext.img_display import ImageDisplayer, register_image_displayer
@register_image_displayer("my-image-display-method")
class MyImageDisplayer(ImageDisplayer):
# Draws image placed in path
def draw(self, path, start_x, start_y, width, height):
# implement me
# Clears the area of the screen where the image was before drawing a preview of another file
def clear(self, start_x, start_y, width, height):
# implement me
- Ensure the following lines appear in your
~/.config/ranger/rc.conf
:
set preview_images true
set preview_images_method my-image-display-method
set use_preview_script true
set preview_script ~/path/to/your/scope.sh # or whatever your preview script is
See ranger/ext/img_preview.py
or the above mpv-based image preview for examples.
- Add the following lines to your
~/.config/ranger/commands.py
:
from ranger.ext.img_display import ImageDisplayer, register_image_displayer
import subprocess
from shlex import quote
@register_image_displayer("wezterm-image-display-method")
class WeztermImageDisplayer(ImageDisplayer):
def draw(self, path, start_x, start_y, width, height):
print("\033[%d;%dH" % (start_y, start_x+1))
path = quote(path)
draw_cmd = "wezterm imgcat {} --width {} --height {}".format(path, width, height)
subprocess.run(draw_cmd.split(" "))
def clear(self, start_x, start_y, width, height):
cleaner = " "*width
for i in range(height):
print("\033[%d;%dH" % (start_y+i, start_x+1))
print(cleaner)
- Ensure the following lines appear in your
~/.config/ranger/rc.conf
:
set preview_images true
set preview_images_method wezterm-image-display-method
set use_preview_script true
set preview_script ~/path/to/your/scope.sh # or whatever your preview script is
If the w3m program doesn't show images itself, then ranger won't show them either in the w3mimgdisplay mode. Try w3m xkcd.com
for example.
Sometimes black stripes are drawn over the images when using w3mimgdisplay. This is due to the unreliable drawing mechanism, and for some people it helps to set the option draw_borders
to true.
Sometimes it helps trying a different terminal emulator or a different displaying method.
w3mimgdisplay appears not to work with compositing managers like xcompmgr.
If your image previews broke after upgrading ranger's git after september 2015, you need to update scope.sh for image previews to work. See https://github.com/hut/ranger/wiki/Upgrading#image-previews-stopped-working-after-updating-ranger-git
Oldschool ASCII art previews can be enabled like this:
- install libcaca (or whatever package provides the "img2txt" executable)
- get a current scope.sh config, e.g. with
ranger --copy-config=scope
- The following
~/.config/ranger/rc.conf
settings are also essential, though the default rc.conf already includes them, so usually you don't need to change anything.
set preview_images false
set use_preview_script true
set preview_script ~/path/to/your/scope.sh
set preview_images false
is necessary because otherwise ranger might use full color previews instead.
Add the following to scope.sh
just before image/*)
. It handles Canon (.CR2
), Olympus (.ORF
), and Sony (.ARW
, which at least xdg-mime query filetype <file>
recognizes as image/tiff
). Expects the exiftool
command to be available.
handle_image() {
local mimetype="${1}"
case "${mimetype}" in
# SVG
# image/svg+xml)
# convert "${FILE_PATH}" "${IMAGE_CACHE_PATH}" && exit 6
# exit 1;;
# BEGIN SNIPPET
image/x-canon-cr2|image/x-olympus-orf|image/tiff)
local orientation
# extract orientation from RAW file using exiftool (identify won't work)
orientation=$( exiftool -b -Orientation "${FILE_PATH}")
exiftool -b -PreviewImage "${FILE_PATH}" > "${IMAGE_CACHE_PATH}"
if [[ -n "$orientation" && "$orientation" != 1 ]]; then
# ...auto-rotate the image according to the EXIF data.
exiftool -overwrite_original_in_place -Orientation="$orientation" -n "${IMAGE_CACHE_PATH}"
mogrify -auto-orient "${IMAGE_CACHE_PATH}"
fi
exit 6;;
# END SNIPPET
# Image
image/*)
local orientation
local orientation
orientation="$( identify -format '%[EXIF:Orientation]\n' -- "${FILE_PATH}" )"