mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-10-31 16:07:30 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			167 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			167 lines
		
	
	
		
			4.4 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, sys
 | |
| 
 | |
| _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)
 | |
| 
 | |
| ##
 | |
| # Displays a given image.
 | |
| #
 | |
| # @param image An image object.
 | |
| # @param title Optional title.  Not all viewers can display the title.
 | |
| # @param **options Additional viewer options.
 | |
| # @return True if a suitable viewer was found, false otherwise.
 | |
| 
 | |
| def show(image, title=None, **options):
 | |
|     for viewer in _viewers:
 | |
|         if viewer.show(image, title=title, **options):
 | |
|             return 1
 | |
|     return 0
 | |
| 
 | |
| ##
 | |
| # Base class for viewers.
 | |
| 
 | |
| class Viewer:
 | |
| 
 | |
|     # 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)
 | |
| 
 | |
|         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 /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, file, 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):
 | |
|                 # FIXME: make sure it's executable
 | |
|                 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, file, 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:
 | |
|                 # FIXME: do full escaping
 | |
|                 command = command + " -name \"%s\"" % 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:]))
 |