mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-09-22 20:09:04 +03:00
d50445ff30
Similar to the recent adoption of Black. isort is a Python utility to sort imports alphabetically and automatically separate into sections. By using isort, contributors can quickly and automatically conform to the projects style without thinking. Just let the tool do it. Uses the configuration recommended by the Black to avoid conflicts of style. Rewrite TestImageQt.test_deprecated to no rely on import order.
224 lines
5.8 KiB
Python
224 lines
5.8 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
|
|
|
|
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 = "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 = "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:]))
|