Package Pmv :: Module colorMap
[hide private]
[frames] | no frames]

Source Code for Module Pmv.colorMap

  1  ############################################################################# 
  2  # 
  3  # Author: Michel F. SANNER 
  4  # 
  5  # Copyright: M. Sanner TSRI 2000 
  6  # 
  7  ############################################################################# 
  8   
  9  # 
 10  # $Header: /opt/cvs/python/packages/share1.5/Pmv/colorMap.py,v 1.1.1.1 2001/04/03 19:47:44 gillet Exp $ 
 11  # 
 12  # $Id: colorMap.py,v 1.1.1.1 2001/04/03 19:47:44 gillet Exp $ 
 13  # 
 14  from Tkinter import * 
 15  from DejaVu.colorTool import RGBRamp, ToRGB, ToHSV 
 16  import types, Numeric 
 17   
18 -class ColorMapGUI(Frame):
19
20 - def button_cb(self, event=None):
21 """call back function for the buttons allowing to toggle between 22 different canvases. 23 This function hides the currentCanvas and shows the canvas 24 corresponding to the active radio button. 25 In addition it sets 26 self.currentCanvas : used to hide it next time we come in 27 self.currentLines : list of Canvas Line objects (one per canvas) 28 self.currentValues : list of numerical values (one per canvas) 29 self.getColor = function to be called to represent a color as a 30 Tk string 31 """ 32 var = self.currentCanvasVar.get() 33 newCanvas = self.canvas[var] 34 self.currentCanvas.forget() 35 newCanvas.pack(side=TOP) 36 self.currentCanvas = newCanvas 37 self.currentLines = self.lines[var] 38 self.currentValues = self.values[var] 39 self.getColor = self.getColorFunc[var] 40 self.current = var
41 42
43 - def hueColor(self, val):
44 """TkColorString <- hueColor(val) 45 val is an integer between 25 and 200. 46 returns color to be use to draw hue lines in hue canvas 47 """ 48 return self.hueColor[val-25]
49 50
51 - def satColor(self, val):
52 """TkColorString <- satColor(val) 53 val is an integer between 25 and 200 54 returns color to be use to draw saturation lines in saturation canvas 55 """ 56 return self.saturationCol[val-25]
57 58
59 - def valColor(self, val):
60 """TkColorString <- satColor(val) 61 val is an integer between 25 and 200 62 returns color to be use to draw value and opacity lines in canvas 63 """ 64 h = hex(val)[2:] 65 if len(h)==1: h = '0'+h 66 return '#'+h+h+h
67 68
69 - def createWidgets(self):
70 """create Tkinter widgets: 4 canvas and buttons in 2 frames 71 """ 72 # create 4 canvas 73 self.canvas = {} 74 self.canvas['Hue'] = Canvas(self, relief=SUNKEN, borderwidth=3, 75 width="200", height="256") 76 self.canvas['Hue'].pack(side=TOP) 77 78 self.canvas['Sat'] = Canvas(self, relief=SUNKEN, borderwidth=3, 79 width="200", height="256") 80 81 self.canvas['Val'] = Canvas(self, relief=SUNKEN, borderwidth=3, 82 width="200", height="256") 83 84 self.canvas['Opa'] = Canvas(self, relief=SUNKEN, borderwidth=3, 85 width="200", height="256") 86 87 # create frame for min max 88 self.minTk = StringVar() 89 self.minTk.set(str(self.min)) 90 self.maxTk = StringVar() 91 self.maxTk.set(str(self.max)) 92 93 minmaxFrame = Frame(self) 94 Label(minmaxFrame, text='Min: ').grid(row=0, column=0, sticky='e') 95 self.minEntry = Entry(minmaxFrame, textvariable=self.minTk) 96 self.minEntry.bind('<Return>', self.min_cb) 97 self.minEntry.grid(row=0, column=1, sticky='w') 98 99 Label(minmaxFrame, text='Max: ').grid(row=1, column=0, sticky='e') 100 self.maxEntry = Entry(minmaxFrame, textvariable=self.maxTk) 101 self.maxEntry.bind('<Return>', self.max_cb) 102 self.maxEntry.grid(sticky='w', row=1, column=1 ) 103 minmaxFrame.pack() 104 105 self.dissmiss = Button(self, text='Dissmiss', command=self.quit) 106 self.dissmiss.pack(side=BOTTOM, fill=X) 107 108 # create frame for buttons 109 self.buttonFrame = Frame(self) 110 111 # create radio buttons to switch between canvas 112 self.buttonFrame1 = f = Frame(self.buttonFrame) 113 self.currentCanvasVar = StringVar() 114 self.buttonHue = Radiobutton(f, text='Hue', value = 'Hue', 115 indicatoron = 0, width=15, 116 variable = self.currentCanvasVar, 117 command=self.button_cb) 118 self.buttonHue.grid(column=0, row=0, sticky='w') 119 120 self.buttonSat = Radiobutton(f, text='Saturation', value = 'Sat', 121 indicatoron = 0, width=15, 122 variable = self.currentCanvasVar, 123 command=self.button_cb) 124 self.buttonSat.grid(column=0, row=1, sticky='w') 125 126 self.buttonVal = Radiobutton(f, text='Brightness', value = 'Val', 127 indicatoron = 0, width=15, 128 variable = self.currentCanvasVar, 129 command=self.button_cb) 130 self.buttonVal.grid(column=0, row=2, sticky='w') 131 132 self.buttonOpa = Radiobutton(f, text='Opacity', value = 'Opa', 133 indicatoron = 0, width=15, 134 variable = self.currentCanvasVar, 135 command=self.button_cb) 136 self.buttonOpa.grid(column=0, row=3, sticky='w') 137 f.pack(side=LEFT) 138 139 self.currentCanvas = self.canvas['Hue'] 140 self.currentCanvasVar.set('Hue') 141 142 # create radio buttons to switch between canvas 143 self.buttonFrame2 = f = Frame(self.buttonFrame) 144 self.reset = Button(f, text='Reset', width=10, command=self.reset_cb) 145 self.reset.grid(column=0, row=1, sticky='w') 146 self.read = Button(f, text='Read', width=10, command=self.read_cb) 147 self.read.grid(column=0, row=2, sticky='w') 148 self.write = Button(f, text='Write', width=10, command=self.write_cb) 149 self.write.grid(column=0, row=3, sticky='w') 150 f.pack(side=LEFT) 151 self.buttonFrame.pack(side=BOTTOM)
152 153
154 - def min_cb(self, event):
155 min = float(self.minTk.get()) 156 if min < self.max: 157 self.min = min 158 self.callCallbacks() 159 else: 160 min = self.max-255.0 161 self.minTk.set(str(min)) 162 self.min = min
163
164 - def max_cb(self, event):
165 max = float(self.maxTk.get()) 166 if max > self.min: 167 self.max = max 168 self.callCallbacks() 169 else: 170 max = self.min+255.0 171 self.maxTk.set(str(max)) 172 self.max = max
173 174
175 - def quit(self):
176 self.master.destroy()
177 178
179 - def reset_cb(self):
180 var = self.currentCanvasVar.get() 181 182 self.clear(var) 183 if var == 'Hue': 184 self.rampHue() 185 self.drawHue() 186 elif var == 'Sat': 187 self.constantSaturation(200) 188 self.drawSaturation() 189 elif var == 'Val': 190 self.constantValue(200) 191 self.drawValue() 192 elif var == 'Opa': 193 self.rampOpacity() 194 self.drawOpacity() 195 self.mouseUp(None) # to call callbacks
196 197
198 - def read_cb(self):
199 print 'read'
200 201
202 - def write_cb(self):
203 print 'write'
204 205
206 - def clear(self, name):
207 assert name in ['Hue', 'Sat', 'Val', 'Opa' ] 208 l = self.lines[name] 209 c = self.canvas[name] 210 for i in range(256): 211 c.delete(l[i]) 212 self.lines[name] = [] 213 self.values[name] = [] 214 if self.current==name: 215 self.currentLines = self.lines[name] 216 self.currentValues = self.values[name]
217
218 - def rampHue(self):
219 ramp = RGBRamp(176) 220 self.hueFromRGB = map( lambda x, conv=ToHSV: conv(x)[0], ramp ) 221 ramp = (ramp*255).astype('i') 222 for i in range(176): 223 r = hex(int(ramp[i][0]))[2:] 224 if len(r)==1: r='0'+r 225 g = hex(ramp[i][1])[2:] 226 if len(g)==1: g='0'+g 227 b = hex(ramp[i][2])[2:] 228 if len(b)==1: b='0'+b 229 self.hueColor.append( '#'+r+g+b) 230 231 v = self.values['Hue'] 232 for i in range(256): 233 v.append(int(i*(175./255.)+25))
234 235
236 - def drawHue(self):
237 l = self.lines['Hue'] 238 c = self.canvas['Hue'] 239 v = self.values['Hue'] 240 for i in range(256): 241 val = v[i] 242 col = self.hueColor[val-25] 243 l.append( c.create_line( 0, i, val, i, fill=col) )
244 245
246 - def constantSaturation(self, value):
247 for i in range(176, -1, -1): 248 h = hex(int(i*174/255.))[2:] 249 if len(h)==1: h='0'+h 250 self.saturationCol.append( '#ff'+h+h ) 251 252 v = [] 253 for i in range(256): 254 v.append(value) 255 self.values['Sat'] = v 256 257 if self.current=='Sat': 258 self.currentValues = v
259 260
261 - def drawSaturation(self):
262 c = self.canvas['Sat'] 263 l = self.lines['Sat'] 264 v = self.values['Sat'] 265 for i in range(256): 266 val = v[i] 267 l.append( c.create_line( 0, i, val, i, fill='red') ) 268 269 if self.current=='Sat': 270 self.currentLines = l
271 272
273 - def constantValue(self, value):
274 v = [] 275 for i in range(256): 276 v.append(value) 277 self.values['Val'] = v 278 if self.current=='Val': 279 self.currentValues = v
280 281
282 - def drawValue(self):
283 c = self.canvas['Val'] 284 l = self.lines['Val'] 285 v = self.values['Val'] 286 for i in range(256): 287 l.append( c.create_line( 0, i, v[i], i, fill='white') ) 288 289 if self.current=='Val': 290 self.currentLines = l
291 292
293 - def rampOpacity(self):
294 v = [] 295 for i in range(256): 296 v.append(int(i*(175./255.)+25)) 297 self.values['Opa'] = v 298 if self.current=='Opa': 299 self.currentValues = v
300 301
302 - def drawOpacity(self):
303 c = self.canvas['Opa'] 304 l = self.lines['Opa'] 305 v = self.values['Opa'] 306 for i in range(256): 307 val = v[i] 308 col = self.valColor(val-25) 309 l.append( c.create_line( 0, i, val, i, fill=col) ) 310 if self.current=='Opa': 311 self.currentLines = l
312 313
314 - def addCallback(self, function):
315 assert callable(function) 316 self.callbacks.append( function )
317 318
319 - def buildRamp(self):
320 h = map( lambda x, table=self.hueFromRGB: table[x-25], 321 self.values['Hue'] ) 322 h = Numeric.array(h) 323 #h = (Numeric.array(self.values['Hue'])-25)/175.0 324 s = (Numeric.array(self.values['Sat'])-25)/175.0 325 v = (Numeric.array(self.values['Val'])-25)/175.0 326 a = (Numeric.array(self.values['Opa'])-25)/175.0 327 self.hsva = map( None, h,s,v,a ) 328 self.rgbMap = map( ToRGB, self.hsva)
329 330
331 - def callCallbacks(self):
332 for f in self.callbacks: 333 f( self.rgbMap, self.min, self.max )
334 335
336 - def mouseUp(self, event):
337 self.buildRamp() 338 self.callCallbacks()
339 340
341 - def mouseDown(self, event):
342 # canvas x and y take the screen coords from the event and translate 343 # them into the coordinate system of the canvas object 344 x = min(199, event.x) 345 y = min(255, event.y) 346 x = max(25, x) 347 y = max(0, y) 348 349 c = self.currentCanvas 350 self.starty = y 351 line = self.currentLines[y] 352 col = self.getColor(x) 353 newline = c.create_line( 0, y, x, y, fill=col) 354 self.currentLines[y] = newline 355 self.currentValues[y] = x 356 c.delete(line) 357 self.startx = x
358 359
360 - def mouseMotion(self, event):
361 # canvas x and y take the screen coords from the event and translate 362 # them into the coordinate system of the canvas object 363 364 # x,y are float 365 #x = self.canvasHue.canvasx(event.x) 366 #y = self.canvasHue.canvasy(event.y) 367 368 # event.x, event.y are same as x,y but int 369 x = min(199, event.x) 370 y = min(255, event.y) 371 x = max(25, x) 372 y = max(0, y) 373 c = self.currentCanvas 374 if self.starty == y: 375 line = self.currentLines[y] 376 col = self.getColor(x) 377 newline = c.create_line( 0, y, x, y, fill=col) 378 self.currentLines[y] = newline 379 c.delete(line) 380 self.currentValues[y] = x 381 382 else: # we need to interpolate for all y's between self.starty and y 383 dx = x-self.startx 384 dy = y-self.starty 385 rat = float(dx)/float(dy) 386 if y > self.starty: 387 for yl in range(self.starty, y): 388 ddx = int(rat*(yl-self.starty)) + self.startx 389 line = self.currentLines[yl] 390 col = self.getColor(ddx) 391 newline = c.create_line( 0,yl, ddx,yl,fill=col) 392 self.currentLines[yl] = newline 393 c.delete(line) 394 self.currentValues[yl] = ddx 395 else: 396 for yl in range(self.starty, y, -1): 397 ddx = int(rat*(yl-self.starty)) + self.startx 398 line = self.currentLines[yl] 399 col = self.getColor(ddx) 400 newline = c.create_line( 0,yl, ddx,yl,fill=col) 401 self.currentLines[yl] = newline 402 c.delete(line) 403 self.currentValues[yl] = ddx 404 self.starty = y 405 self.startx = x 406 407 # this flushes the output, making sure that 408 # the rectangle makes it to the screen 409 # before the next event is handled 410 self.update_idletasks()
411 412
413 - def __init__(self, master=None, min=0.0, max=255.0):
414 if master == None: 415 master = Toplevel() 416 Frame.__init__(self, master) 417 Pack.config(self) 418 419 self.min=min 420 self.max=max 421 self.getColorFunc = { 'Hue':self.hueColor, 422 'Sat':self.satColor, 423 'Val':self.valColor, 424 'Opa':self.valColor 425 } 426 427 self.values = { 'Hue': [], 428 'Sat': [], 429 'Val': [], 430 'Opa': [] 431 } 432 self.lines = { 'Hue':[], 'Sat':[], 'Val':[], 'Opa':[] } 433 self.current = 'Hue' 434 self.currentLines = None 435 self.currentValues = None 436 437 self.hueColor = [] 438 self.saturationCol = [] 439 440 self.callbacks = [] 441 self.hueFromRGB = [] 442 443 self.createWidgets() 444 self.rampHue() 445 self.drawHue() 446 self.constantSaturation(200) 447 self.drawSaturation() 448 self.constantValue(200) 449 self.drawValue() 450 self.rampOpacity() 451 self.drawOpacity() 452 # just so we have the corresponfing RGBramp 453 self.buildRamp() 454 455 self.getColor = self.getColorFunc['Hue'] 456 self.currentLines = self.lines['Hue'] 457 self.currentValues = self.values['Hue'] 458 459 Widget.bind(self.canvas['Hue'], "<ButtonPress-1>", self.mouseDown) 460 Widget.bind(self.canvas['Hue'], "<Button1-Motion>", self.mouseMotion) 461 Widget.bind(self.canvas['Hue'], "<ButtonRelease-1>", self.mouseUp) 462 Widget.bind(self.canvas['Sat'], "<ButtonPress-1>", self.mouseDown) 463 Widget.bind(self.canvas['Sat'], "<Button1-Motion>", self.mouseMotion) 464 Widget.bind(self.canvas['Sat'], "<ButtonRelease-1>", self.mouseUp) 465 Widget.bind(self.canvas['Val'], "<ButtonPress-1>", self.mouseDown) 466 Widget.bind(self.canvas['Val'], "<Button1-Motion>", self.mouseMotion) 467 Widget.bind(self.canvas['Val'], "<ButtonRelease-1>", self.mouseUp) 468 Widget.bind(self.canvas['Opa'], "<ButtonPress-1>", self.mouseDown) 469 Widget.bind(self.canvas['Opa'], "<Button1-Motion>", self.mouseMotion) 470 Widget.bind(self.canvas['Opa'], "<ButtonRelease-1>", self.mouseUp)
471 472 473 if __name__ == '__main__': 474 import pdb 475 test = ColorMapGUI()
476 - def cb(ramp, min, max):
477 print len(ramp), min, max
478 test.addCallback(cb) 479 #test.mainloop() 480