mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-10-31 16:07:30 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			177 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			177 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #
 | |
| # 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
 | |
| 
 | |
| from PIL import Image
 | |
| import os
 | |
| import sys
 | |
| 
 | |
| if sys.version_info >= (3, 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 image.mode[:4] == "I;16":
 | |
|             # @PIL88 @PIL101
 | |
|             # "I;16" isn't an 'official' mode, but we still want to
 | |
|             # provide a simple way to show 16-bit images.
 | |
|             base = "L"
 | |
|             # FIXME: auto-contrast if max() > 255?
 | |
|         else:
 | |
|             base = Image.getmodebase(image.mode)
 | |
|         if base != image.mode and image.mode != "1":
 | |
|             image = image.convert(base)
 | |
| 
 | |
|         return self.show_image(image, **options)
 | |
| 
 | |
|     # hook methods
 | |
| 
 | |
|     format = None
 | |
| 
 | |
|     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))
 | |
| 
 | |
|     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 = "BMP"
 | |
| 
 | |
|         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 = "BMP"
 | |
| 
 | |
|         def get_command(self, file, **options):
 | |
|             # on darwin open returns immediately resulting in the temp
 | |
|             # file removal while app is opening
 | |
|             command = "open -a /Applications/Preview.app"
 | |
|             command = "(%s %s; sleep 20; rm -f %s)&" % (command, quote(file),
 | |
|                                                         quote(file))
 | |
|             return command
 | |
| 
 | |
|     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):
 | |
|         def show_file(self, file, **options):
 | |
|             command, executable = self.get_command_ex(file, **options)
 | |
|             command = "(%s %s; rm -f %s)&" % (command, quote(file),
 | |
|                                               quote(file))
 | |
|             os.system(command)
 | |
|             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 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__":
 | |
|     # usage: python ImageShow.py imagefile [title]
 | |
|     print(show(Image.open(sys.argv[1]), *sys.argv[2:]))
 |