mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-26 18:06:18 +03:00
dbf3d993ed
The issue was reported several times during the past years. The temporary bitmap file is deleted before the image viewer is started. The workaround is to wait some time before deleting the file. http://stackoverflow.com/questions/4607633/image-format-to-save-in-python http://stackoverflow.com/questions/7715501/pil-image-show-doesnt-work-on-windows-7
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 . 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:]))
|