48
48
# Added _imroot.lift() to ensure that pictures aren't hidden under other Windows
49
49
# (needed on Windows 7 & Python 3.4. Ubuntu 14.04 was fine without it).
50
50
#
51
- # version 1.4
51
+ # version 1.4
52
52
# Brad Miller
53
53
# distribute on pypi
54
54
#
65
65
# Force the Pixel object to store all rgb values as int's, to avoid students getting errors when
66
66
# they divide in their image manipulation calculations
67
67
# Make EmptyImage's show up with white backgrounds, for both PIL and tkinter
68
+ # Version 1.5 May 2016 Max Hailperin <[email protected] >
69
+ # Changes:
70
+ # Add more checks of parameter types and ranges so error messages are
71
+ # closer to the user's code and more intelligible.
72
+ # Disable the ability of Pixels to range up to 1.0 instead of 255, which
73
+ # didn't seem used and would make the type checking more complex.
74
+ #
75
+ # Version 1.6 May 2016 Max Hailperin <[email protected] >
76
+ # Changes:
77
+ # Add autoShow function that can be used to get and optionally set a flag
78
+ # that if True makes images automatically be displayed when their printed
79
+ # representation is produced (e.g. as results in the shell).
68
80
69
81
try :
70
82
import tkinter
95
107
#_imroot.after_idle(_imroot.call, 'wm', 'attributes', '.', '-topmost', False)
96
108
97
109
110
+ # For backward compatibility, the new autoShow feature is off by default:
111
+ autoShowOn = False
112
+
113
+ def autoShow (newSetting = None ):
114
+ """Return and optionally change the True/False autoShow setting"""
115
+ global autoShowOn
116
+ oldSetting = autoShowOn
117
+ if newSetting != None :
118
+ autoShowOn = newSetting
119
+ return oldSetting
120
+
98
121
def formatPixel (data ):
99
122
if type (data ) == tuple :
100
123
return '{#%02x%02x%02x}' % data
@@ -175,10 +198,10 @@ class Pixel(object):
175
198
"""This simple class abstracts the RGB pixel values."""
176
199
def __init__ (self , red , green , blue ):
177
200
super (Pixel , self ).__init__ ()
178
- self .__red = red
179
- self .__green = green
180
- self .__blue = blue
181
201
self .max = 255
202
+ self .setRed (red )
203
+ self .setGreen (green )
204
+ self .setBlue (blue )
182
205
183
206
def getRed (self ):
184
207
"""Return the red component of the pixel"""
@@ -210,8 +233,10 @@ def get_color_tuple(self):
210
233
211
234
def setRed (self ,red ):
212
235
"""Modify the red component"""
213
- if self .max >= red >= 0 :
214
- self .__red = int (red )
236
+ if not isinstance (red , int ):
237
+ raise TypeError ("Error: pixel value %r is not an integer" % red )
238
+ elif self .max >= red >= 0 :
239
+ self .__red = red
215
240
else :
216
241
raise ValueError ("Error: pixel value %d is out of range" % red )
217
242
@@ -220,8 +245,10 @@ def set_red(self, red):
220
245
221
246
def setGreen (self ,green ):
222
247
"""Modify the green component"""
223
- if self .max >= green >= 0 :
224
- self .__green = int (green )
248
+ if not isinstance (green , int ):
249
+ raise TypeError ("Error: pixel value %r is not an integer" % green )
250
+ elif self .max >= green >= 0 :
251
+ self .__green = green
225
252
else :
226
253
raise ValueError ("Error: pixel value %d is out of range" % green )
227
254
@@ -230,8 +257,10 @@ def set_green(self, green):
230
257
231
258
def setBlue (self ,blue ):
232
259
"""Modify the blue component"""
233
- if self .max >= blue >= 0 :
234
- self .__blue = int (blue )
260
+ if not isinstance (blue , int ):
261
+ raise TypeError ("Error: pixel value %r is not an integer" % blue )
262
+ elif self .max >= blue >= 0 :
263
+ self .__blue = blue
235
264
else :
236
265
raise ValueError ("Error: pixel value %d is out of range" % blue )
237
266
@@ -258,6 +287,10 @@ def __getitem__(self,key):
258
287
def setRange (self ,pmax ):
259
288
"""docstring for setRange"""
260
289
if pmax == 1.0 :
290
+ raise ValueError ("Range of 1.0 is not currently supported" )
291
+ # This raising of an error was inserted in conjunction with
292
+ # requiring the values to be integers, which is necessary for
293
+ # formatPixel to work correctly. Was 1.0 ever used?
261
294
self .max = 1.0
262
295
elif pmax == 255 :
263
296
self .max = 255
@@ -513,19 +546,40 @@ def toList(self):
513
546
def to_list (self ):
514
547
return self .toList ()
515
548
549
+ def __repr__ (self ):
550
+ r = super (AbstractImage , self ).__repr__ ()
551
+ if autoShowOn :
552
+ w = ImageWin (r , self .width , self .height )
553
+ self .draw (w )
554
+ return r
555
+
556
+
516
557
class FileImage (AbstractImage ):
517
558
def __init__ (self ,thefile ):
559
+ if not isinstance (thefile , str ):
560
+ raise TypeError ("Error: file name %r not a string" % thefile )
518
561
super (FileImage , self ).__init__ (fname = thefile )
519
562
520
563
class Image (FileImage ):
521
564
pass
522
565
523
566
class EmptyImage (AbstractImage ):
524
567
def __init__ (self ,cols ,rows ):
568
+ if not isinstance (cols , int ):
569
+ raise TypeError ("Error: width %r not an integer" % cols )
570
+ if cols <= 0 :
571
+ raise ValueError ("Error: width %d not positive" % cols )
572
+ if not isinstance (rows , int ):
573
+ raise TypeError ("Error: height %r not an integer" % rows )
574
+ if rows <= 0 :
575
+ raise ValueError ("Error: height %d not positive" % rows )
525
576
super (EmptyImage , self ).__init__ (height = rows , width = cols )
526
577
527
578
class ListImage (AbstractImage ):
528
579
def __init__ (self ,thelist ):
580
+ # Note that the corresponding code in AbstractImage doesn't work
581
+ # so apparently ListImage isn't used. As such, there doesn't seem
582
+ # to be much point in adding error checking.
529
583
super (ListImage , self ).__init__ (data = thelist )
530
584
531
585
# Example program Read in an image and calulate the negative.
0 commit comments