-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
Copy pathImageShow.py
163 lines (128 loc) · 4.35 KB
/
ImageShow.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#
# 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.
#
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 && 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:])