123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- #
- # The Python Imaging Library.
- # $Id$
- #
- # im.show() drivers
- #
- # History:
- # 2008-04-06 fl Created
- #
- # Copyright (c) Secret Labs AB 2008.
- #
- # See the README file for information on usage and redistribution.
- #
- from __future__ import print_function
- import os
- import subprocess
- import sys
- import tempfile
- from PIL import Image
- if sys.version_info.major >= 3:
- from shlex import quote
- else:
- from pipes import quote
- _viewers = []
- def register(viewer, order=1):
- try:
- if issubclass(viewer, Viewer):
- viewer = viewer()
- except TypeError:
- pass # raised if viewer wasn't a class
- if order > 0:
- _viewers.append(viewer)
- elif order < 0:
- _viewers.insert(0, viewer)
- def show(image, title=None, **options):
- r"""
- Display a given image.
- :param image: An image object.
- :param title: Optional title. Not all viewers can display the title.
- :param \**options: Additional viewer options.
- :returns: True if a suitable viewer was found, false otherwise.
- """
- for viewer in _viewers:
- if viewer.show(image, title=title, **options):
- return 1
- return 0
- class Viewer(object):
- """Base class for viewers."""
- # main api
- def show(self, image, **options):
- # save temporary image to disk
- if not (
- image.mode in ("1", "RGBA") or (self.format == "PNG" and image.mode == "LA")
- ):
- base = Image.getmodebase(image.mode)
- if image.mode != base:
- image = image.convert(base)
- return self.show_image(image, **options)
- # hook methods
- format = None
- options = {}
- def get_format(self, image):
- """Return format name, or None to save as PGM/PPM"""
- return self.format
- def get_command(self, file, **options):
- raise NotImplementedError
- def save_image(self, image):
- """Save to temporary file, and return filename"""
- return image._dump(format=self.get_format(image), **self.options)
- def show_image(self, image, **options):
- """Display given image"""
- return self.show_file(self.save_image(image), **options)
- def show_file(self, file, **options):
- """Display given file"""
- os.system(self.get_command(file, **options))
- return 1
- # --------------------------------------------------------------------
- if sys.platform == "win32":
- class WindowsViewer(Viewer):
- format = "PNG"
- options = {"compress_level": 1}
- def get_command(self, file, **options):
- return (
- 'start "Pillow" /WAIT "%s" '
- "&& ping -n 2 127.0.0.1 >NUL "
- '&& del /f "%s"' % (file, file)
- )
- register(WindowsViewer)
- elif sys.platform == "darwin":
- class MacViewer(Viewer):
- format = "PNG"
- options = {"compress_level": 1}
- def get_command(self, file, **options):
- # on darwin open returns immediately resulting in the temp
- # file removal while app is opening
- command = "open -a Preview.app"
- command = "(%s %s; sleep 20; rm -f %s)&" % (
- command,
- quote(file),
- quote(file),
- )
- return command
- def show_file(self, file, **options):
- """Display given file"""
- fd, path = tempfile.mkstemp()
- with os.fdopen(fd, "w") as f:
- f.write(file)
- with open(path, "r") as f:
- subprocess.Popen(
- ["im=$(cat); open -a Preview.app $im; sleep 20; rm -f $im"],
- shell=True,
- stdin=f,
- )
- os.remove(path)
- return 1
- register(MacViewer)
- else:
- # unixoids
- def which(executable):
- path = os.environ.get("PATH")
- if not path:
- return None
- for dirname in path.split(os.pathsep):
- filename = os.path.join(dirname, executable)
- if os.path.isfile(filename) and os.access(filename, os.X_OK):
- return filename
- return None
- class UnixViewer(Viewer):
- format = "PNG"
- options = {"compress_level": 1}
- def get_command(self, file, **options):
- command = self.get_command_ex(file, **options)[0]
- return "(%s %s; rm -f %s)&" % (command, quote(file), quote(file))
- def show_file(self, file, **options):
- """Display given file"""
- fd, path = tempfile.mkstemp()
- with os.fdopen(fd, "w") as f:
- f.write(file)
- with open(path, "r") as f:
- command = self.get_command_ex(file, **options)[0]
- subprocess.Popen(
- ["im=$(cat);" + command + " $im; rm -f $im"], shell=True, stdin=f
- )
- os.remove(path)
- return 1
- # implementations
- class DisplayViewer(UnixViewer):
- def get_command_ex(self, file, **options):
- command = executable = "display"
- return command, executable
- if which("display"):
- register(DisplayViewer)
- class EogViewer(UnixViewer):
- def get_command_ex(self, file, **options):
- command = executable = "eog"
- return command, executable
- if which("eog"):
- register(EogViewer)
- class XVViewer(UnixViewer):
- def get_command_ex(self, file, title=None, **options):
- # note: xv is pretty outdated. most modern systems have
- # imagemagick's display command instead.
- command = executable = "xv"
- if title:
- command += " -name %s" % quote(title)
- return command, executable
- if which("xv"):
- register(XVViewer)
- if __name__ == "__main__":
- if len(sys.argv) < 2:
- print("Syntax: python ImageShow.py imagefile [title]")
- sys.exit()
- print(show(Image.open(sys.argv[1]), *sys.argv[2:]))
|