-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathgraphic.py
249 lines (205 loc) · 7.59 KB
/
graphic.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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
#!/usr/bin/python
# -*- coding: utf-8 -*-
"gui2py's Graphic facilities (encapsulate wx.Bitmap and wx.Color)"
__author__ = "Mariano Reingart (reingart@gmail.com)"
__copyright__ = "Copyright (C) 2013- Mariano Reingart" # where applicable
# Initial implementation was based on PythonCard's graphic module, altought
# some of it was redesigned and overhauled a lot (specially Color)
import os
import warnings
import wx
try:
try:
import Image
except ImportError:
from PIL import Image
# necessary to avoid name collision with Image class
from Image import fromstring
PIL_FOUND = 1
except ImportError:
PIL_FOUND = 0
def pil_to_image(pilImage):
if (pilImage.mode != 'RGB'):
pilImage = pilImage.convert('RGB')
imageData = pilImage.tostring('raw', 'RGB')
img = wx.EmptyImage(pilImage.size[0], pilImage.size[1])
img.SetData(imageData)
return img
def pil_to_bitmap(image):
return wx.BitmapFromImage(pil_to_image(image))
def bitmap_to_pil(bmp):
imageData = wx.ImageFromBitmap(bmp).GetData()
imagePIL = fromstring('RGB', (bmp.get_width(), bmp.get_height()), imageData)
imagePIL = imagePIL.convert('RGB')
return imagePIL
def numeric_array_to_image(array):
height, width = array.shape[:2]
img = wx.EmptyImage(width, height)
img.SetData(array.tostring())
return img
def bitmap_type(filename):
"""
Get the type of an image from the file's extension ( .jpg, etc. )
"""
if filename == '':
return None
name, ext = os.path.splitext(filename)
ext = ext[1:].upper()
if ext == 'BMP':
return wx.BITMAP_TYPE_BMP
elif ext == 'GIF':
return wx.BITMAP_TYPE_GIF
elif ext == 'JPG' or ext == 'JPEG':
return wx.BITMAP_TYPE_JPEG
elif ext == 'PCX':
return wx.BITMAP_TYPE_PCX
elif ext == 'PICT':
return wx.BITMAP_TYPE_PICT
elif ext == 'PNG':
return wx.BITMAP_TYPE_PNG
elif ext == 'PNM':
return wx.BITMAP_TYPE_PNM
elif ext == 'TIF' or ext == 'TIFF':
return wx.BITMAP_TYPE_TIF
elif ext == 'XBM':
return wx.BITMAP_TYPE_XBM
elif ext == 'XPM':
return wx.BITMAP_TYPE_XPM
else:
# KEA 2001-10-10
# rather than throw an exception, we could try and have wxPython figure out the image
# type by returning wxBITMAP_TYPE_ANY
raise RuntimeErro('invalid graphics format') # should throw an exception here
def save_window_screenshot(w, path):
bmp = wx.EmptyBitmap(w.size[0], w.size[1])
memdc = wx.MemoryDC()
memdc.SelectObject(bmp)
dc = wx.WindowDC(w)
memdc.BlitPointSize((0, 0), w.size, dc, (0, 0))
bmp.save_file(path, bitmap_type(path))
dc = None
memdc.SelectObject(wx.NullBitmap)
memdc = None
bmp = None
class Bitmap:
def __init__(self, filename=None, size=(-1, -1)):
if filename is None or filename == '':
self._filename = None
else:
self._filename = filename
# KEA 2004-07-27
# Mac checks that the bitmap is Ok() so need
# to use a valid size
if (self._filename is None) and (tuple(size) == (-1, -1)):
self._size = (10, 10)
else:
self._size = size
self._type = None
self.load_file(self._filename, self._size)
def get_bits( self ) :
return self._bits
def set_bits( self, aWxBitmap ) :
self._bits = aWxBitmap
def set_pil_bits(self, image):
self._bits = pil_to_bitmap(image)
def get_pil_bits(self):
return bitmap_to_pil(self._bits)
def set_image_bits(self, image):
self._bits = wx.BitmapFromImage(image)
def get_image_bits(self):
return wx.ImageFromBitmap(self._bits)
def get_height( self ) :
return self._bits.GetHeight()
def get_width( self ) :
return self._bits.GetWidth()
def get_size( self ) :
return (self._bits.get_width(), self._bits.get_height())
# KEA special handling for -2 size option
def set_size( self, aSize ):
raise NotImplementedError
def get_type( self ) :
return self._type
def _getbitmap_type( self, filename ) :
"""
Get the type of an image from the file's extension ( .jpg, etc. )
"""
# KEA 2001-07-27
# was
#name, ext = filename.split( '.' )
#ext = ext.upper()
if filename is None or filename == '':
return None
name, ext = os.path.splitext(filename)
ext = ext[1:].upper()
if ext == 'BMP':
return wx.BITMAP_TYPE_BMP
elif ext == 'GIF':
return wx.BITMAP_TYPE_GIF
elif ext == 'JPG' or ext == 'JPEG':
return wx.BITMAP_TYPE_JPEG
elif ext == 'PCX':
return wx.BITMAP_TYPE_PCX
#elif ext == 'PICT':
# return wx.BITMAP_TYPE_PICT
elif ext == 'PNG':
return wx.BITMAP_TYPE_PNG
elif ext == 'PNM':
return wx.BITMAP_TYPE_PNM
elif ext == 'TIF' or ext == 'TIFF':
return wx.BITMAP_TYPE_TIF
elif ext == 'XBM':
return wx.BITMAP_TYPE_XBM
elif ext == 'XPM':
return wx.BITMAP_TYPE_XPM
else:
# KEA 2001-10-10
# rather than throw an exception, we could try and have wxPython figure out the image
# type by returning wxBITMAP_TYPE_ANY
raise RuntimeError('invalid graphics format') # should throw an exception here
# xbm format doesn't seem to work on Windows
def load_file(self, filename=None, size=(-1, -1)):
if filename is None or filename == '':
self._filename = None
elif not os.path.exists(filename):
# TODO: add an absoulte base path if it is relative
warnings.warn("Image %s not found" % filename, RuntimeWarning)
self._filename = None
else:
self._filename = filename
if (self._filename is None) and (tuple(size) == (-1, -1)):
self._size = (10, 10)
else:
self._size = size
self._type = self._getbitmap_type(self._filename)
if self._type is None:
self._bits = wx.EmptyBitmap(self._size[0], self._size[1])
else:
self._bits = wx.Bitmap(self._filename, self._type)
# attempting to save a GIF image will result in a zero length file
def save_file(self, filename=None):
if filename is None:
filename = self._filename
try:
self._bits.save_file(filename, self._getbitmap_type(filename))
except:
pass
def rotate90(self, clockwise=1):
image = wx.ImageFromBitmap(self._bits)
self._bits = wx.BitmapFromImage(image.Rotate90(clockwise))
def rescale(self, width, height, quality=100):
print "rescaling to", width, height
if self._bits:
try:
image = wx.ImageFromBitmap(self._bits)
self._bits = wx.BitmapFromImage(image.Rescale(width, height, quality))
self.size = (width, height)
except Exception, e:
print "cannot rescale:", e
class Color(wx.Colour):
"Helper to represent the colour and detect if a colour is the default"
default = True
def __repr__(self):
if not self.default:
return repr(self.GetAsString(wx.C2S_HTML_SYNTAX))
else:
return 'None'