ximage.pro
31.7 KB
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
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
;+
; NAME:
; XIMAGE
;
; PURPOSE:
;
; The purpose of this program is to demonstrate how to
; create a image plot with axes,a title, and the ability
; to select a location and image value using object graphics.
;
; AUTHOR:
;
; FANNING SOFTWARE CONSULTING
; David Fanning, Ph.D.
; 1645 Sheely Drive
; Fort Collins, CO 80526 USA
; Phone: 970-221-0438
; E-mail: david@idlcoyote.com
; Coyote's Guide to IDL Programming: http://www.idlcoyote.com
;
; CATEGORY:
;
; Widgets, Object Graphics.
;
; CALLING SEQUENCE:
;
; XImage, image
;
; REQUIRED INPUTS:
;
; None. The image "worldelv.dat" from the examples/data directory
; is used if no data is supplied in call.
;
; OPTIONAL INPUTS
;
; image: An 8-bit or 24-bit image.
;
; OPTIONAL KEYWORD PARAMETERS:
;
; COLORTABLE: The number of a color table to use as the image palette.
; Color table 0 (grayscale) is used as a default. (Keyword ignored if
; a 24-bit image is used.
;
; GROUP_LEADER: The group leader for this program. When the group leader
; is destroyed, this program will be destroyed.
;
; KEEP_ASPECT_RATIO: Set this keyword if you wish the aspect ratio
; of the image to be preserved as the graphics display window is resized.
;
; TITLE: A string used as the title of the plot.
;
; XRANGE: A two-element array specifying the X axis range.
;
; XSIZE: The initial X window size. Default is 400 pixels.
;
; XTITLE: A string used as the X title of the plot.
;
; YRANGE: A two-element array specifying the Y axis range.
;
; YSIZE: The initial Y window size. Default is 400 pixels.
;
; YTITLE: A string used as the Y title of the plot.
;
; COMMON BLOCKS:
;
; None.
;
; SIDE EFFECTS:
;
; None.
;
; RESTRICTIONS:
;
; Requires the XColors and Normalize programs from the Coyote library.
;
; http://www.idlcoyote.com/programs/xcolors.pro
; http://www.idlcoyote.com/programs/normalize.pro
;
; EXAMPLE:
;
; To use this program with your 8-bit or 24-bit image data, type:
;
; IDL> XImage, image
;
; MODIFICATION HISTORY:
;
; Written by David Fanning, 13 June 97.
; Added Keep_Apect_Ratio keyword and Zoom buttons. DWF 15 JUNE 97.
; Improved font handling and color support. DWF 4 OCT 97.
; Fixed memory leakage from improper object cleanup. 12 FEB 98. DWF
; Changed IDLgrContainer to IDL_Container to fix 5.1 problems. 20 May 98. DWF.
; Modified program to show how image values can be selected. 8 May 2000. DWF.
; Made several modifications to resize event handler. Much improved. 2 June 2000. DWF.
; Completely updated program to reflect current (IDL 5.5) capabilities. 12 Nov 2001. DWF.
; Removed NORMALIZE from the source code. 29 November 2005. DWF.
; Renamed NORMALIZE to FSC_NORMALIZE to avoid numerous naming conflicts. 17 October 2008. DWF.
;-
;******************************************************************************************;
; Copyright (c) 2008, by Fanning Software Consulting, Inc. ;
; All rights reserved. ;
; ;
; Redistribution and use in source and binary forms, with or without ;
; modification, are permitted provided that the following conditions are met: ;
; ;
; * Redistributions of source code must retain the above copyright ;
; notice, this list of conditions and the following disclaimer. ;
; * Redistributions in binary form must reproduce the above copyright ;
; notice, this list of conditions and the following disclaimer in the ;
; documentation and/or other materials provided with the distribution. ;
; * Neither the name of Fanning Software Consulting, Inc. nor the names of its ;
; contributors may be used to endorse or promote products derived from this ;
; software without specific prior written permission. ;
; ;
; THIS SOFTWARE IS PROVIDED BY FANNING SOFTWARE CONSULTING, INC. ''AS IS'' AND ANY ;
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ;
; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT ;
; SHALL FANNING SOFTWARE CONSULTING, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, ;
; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED ;
; TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; ;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ;
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ;
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ;
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ;
;******************************************************************************************;
FUNCTION XImage_Aspect, aspectRatio, MARGIN=margin, WindowAspect=wAspectRatio
; This function calculates the correct aspect ratios for printing.
ON_ERROR, 2
; Check for aspect ratio parameter and possibilities.
IF N_PARAMS() EQ 0 THEN aspectRatio = 1.0
IF aspectRatio EQ 0 THEN BEGIN
MESSAGE, 'Aspect Ratio of 0. Changing to 1...', /Informational
aspectRatio = 1.0
ENDIF
s = SIZE(aspectRatio)
IF s(s(0)+1) NE 4 THEN $
MESSAGE, 'Aspect Ratio is not a FLOAT. Take care...', /Informational
; Check for margins.
IF N_ELEMENTS(margin) EQ 0 THEN margin = 0.15
; Error checking.
IF margin LT 0 OR margin GE 0.5 THEN $
MESSAGE, 'The MARGIN keyword value must be between 0.0 and 0.5.'
; Calculate the aspect ratio of the current window.
IF N_Elements(wAspectRatio) EQ 0 THEN wAspectRatio = FLOAT(!D.Y_VSIZE) / !D.X_VSIZE
; Calculate normalized positions in window.
IF (aspectRatio LE wAspectRatio) THEN BEGIN
xstart = margin
ystart = 0.5 - (0.5 - margin) * (aspectRatio / wAspectRatio)
xend = 1.0 - margin
yend = 0.5 + (0.5 - margin) * (aspectRatio / wAspectRatio)
ENDIF ELSE BEGIN
xstart = 0.5 - (0.5 - margin) * (wAspectRatio / aspectRatio)
ystart = margin
xend = 0.5 + (0.5 - margin) * (wAspectRatio / aspectRatio)
yend = 1.0 - margin
ENDELSE
position = [xstart, ystart, xend, yend]
RETURN, position
END
;-------------------------------------------------------------------------
PRO XImage_Zoom_Button_Event, event
; Event handler to perform window zooming.
Widget_Control, event.top, Get_UValue=info, /No_Copy
; What kind of zooming is wanted?
Widget_Control, event.id, Get_UValue=zoomIt
CASE zoomIt OF
'ZOOM_IN': BEGIN
info.plotView->GetProperty, Viewplane_Rect=thisRect
thisRect(0) = (thisRect(0) + 0.05) < thisRect(2)
thisRect(1) = (thisRect(1) + 0.05) < thisRect(3)
thisRect(2) = (thisRect(2) - 0.1) > thisRect(0)
thisRect(3) = (thisRect(3) - 0.1) > thisRect(1)
info.plotView->SetProperty, Viewplane_Rect=thisRect
END
'ZOOM_OUT': BEGIN
info.plotView->GetProperty, Viewplane_Rect=thisRect
thisRect(0) = thisRect(0) - 0.05
thisRect(1) = thisRect(1) - 0.05
thisRect(2) = thisRect(2) + 0.1
thisRect(3) = thisRect(3) + 0.1
info.plotView->SetProperty, Viewplane_Rect=thisRect
END
ENDCASE
; Redisplay the view.
info.thisWindow->Draw, info.plotView
Widget_Control, event.top, Set_UValue=info, /No_Copy
END
;-------------------------------------------------------------------
PRO XImage_Processing, event
; Event handler to perform image processing options.
Widget_Control, event.top, Get_UValue=info, /No_Copy
; What processing is wanted?
Widget_Control, event.id, Get_UValue=thisOperation
CASE thisOperation OF
'SOBEL': data=Sobel(*info.processPtr)
'ROBERTS': data=Roberts(*info.processPtr)
'BOXCAR': data=Smooth(*info.processPtr,5)
'MEDIAN': data=Median(*info.processPtr,5)
'ORIGINAL': data=*info.imagePtr
ENDCASE
; Update image and processed image data.
info.thisImage->SetProperty, Data=BytScl(data)
*info.processPtr = data
; Redisplay the view.
info.thisWindow->Draw, info.plotView
Widget_Control, event.top, Set_UValue=info, /No_Copy
END
;-------------------------------------------------------------------
PRO XImage_Output, event
; This event handler creates output files.
Widget_Control, event.top, Get_UValue=info, /No_Copy
; Get a snapshop of window contents. (TVRD equivalent.)
Wait, 0.5 ; To allow menu to disappear.
info.thisWindow->GetProperty, Image_Data=snapshot
; What kind of file is wanted?
Widget_Control, event.id, GET_UValue=whichFileType
CASE whichFileType OF
'GIF': BEGIN
; Because we are using RGB color for this model, we have
; a 3-m-n array. Use Color_Quan to create a 2D image and
; appropriate color tables for the GIF file.
image2D = Color_Quan(snapshot, 1, r, g, b)
filename = Dialog_Pickfile(/Write, File='ximage.gif')
IF filename NE '' THEN Write_GIF, filename, image2d, r, g, b
END
'BMP': BEGIN
; Because we are using RGB color for this model, we have
; a 3-m-n array. Use Color_Quan to create a 2D image and
; appropriate color tables for the GIF file.
image2D = Color_Quan(snapshot, 1, r, g, b)
filename = Dialog_Pickfile(/Write, File='ximage.bmp')
IF filename NE '' THEN Write_BMP, filename, image2d, r, g, b
END
'PNG': BEGIN
; Because we are using RGB color for this model, we have
; a 3-m-n array. Use Color_Quan to create a 2D image and
; appropriate color tables for the GIF file.
image2D = Color_Quan(snapshot, 1, r, g, b)
filename = Dialog_Pickfile(/Write, File='ximage.png')
IF filename NE '' THEN Write_PNG, filename, image2d, r, g, b
END
'PICT': BEGIN
; Because we are using RGB color for this model, we have
; a 3-m-n array. Use Color_Quan to create a 2D image and
; appropriate color tables for the GIF file.
image2D = Color_Quan(snapshot, 1, r, g, b)
filename = Dialog_Pickfile(/Write, File='ximage.pict')
IF filename NE '' THEN Write_PICT, filename, image2d, r, g, b
END
'JPEG': BEGIN
filename = Dialog_Pickfile(/Write, File='ximage.jpg')
IF filename NE '' THEN Write_JPEG, filename, snapshot, True=1
END
'TIFF': BEGIN
filename = Dialog_Pickfile(/Write, File='ximage.tif')
IF filename NE '' THEN BEGIN
; TIFF files should have their Y direction reversed for
; compatibility with most other software.
Write_TIFF, filename, Reverse(snapshot,3)
ENDIF
END
ENDCASE
;Put the info structure back.
Widget_Control, event.top, Set_UValue=info, /No_Copy
END
;-------------------------------------------------------------------
PRO XImage_Exit, event
; Exit the program via the EXIT button.
; The XIMAGE_CLEANUP procedure will be called automatically.
Widget_Control, event.top, /Destroy
END
;-------------------------------------------------------------------
PRO XImage_Printing, event
; PostScript printing and printer setup handled here.
Widget_Control, event.top, Get_UValue=info, /No_Copy
; Which button?
Widget_Control, event.id, Get_UValue=ButtonValue
CASE buttonValue OF
'PRINT': BEGIN
result = Dialog_PrintJob(info.thisPrinter)
IF result EQ 1 THEN BEGIN
; I want the output on the page to have the same aspect ratio
; (ratio of height to width) as I see in the display window.
info.thisWindow->GetProperty, Dimensions=wdims
info.thisPrinter->GetProperty, Dimensions=pdims
plotAspect = Float(wdims[1]) / wdims[0]
windowAspect = Float(pdims[1]) / pdims[0]
position = XImage_Aspect(plotAspect, WindowAspect=windowAspect, Margin=0.075)
info.plotView->SetProperty, Dimensions=[position[2]-position[0], position[3]-position[1]], $
Location=[position[0], position[1]], Units=3
; Print it. May take a little time. Alert the user.
Widget_Control, Hourglass=1
info.thisPrinter->Draw, info.plotView
info.thisPrinter->NewDocument
Widget_Control, Hourglass=0
; Put things back the way you found them.
info.plotView->SetProperty, Location=[0,0], Dimensions=[0,0]
ENDIF
END
'SETUP': BEGIN
result = Dialog_PrinterSetup(info.thisPrinter)
IF result EQ 1 THEN BEGIN
; I want the output on the page to have the same aspect ratio
; (ratio of height to width) as I see in the display window.
info.thisWindow->GetProperty, Dimensions=wdims
info.thisPrinter->GetProperty, Dimensions=pdims
plotAspect = Float(wdims[1]) / wdims[0]
windowAspect = Float(pdims[1]) / pdims[0]
position = XImage_Aspect(plotAspect, WindowAspect=windowAspect, Margin=0.075)
info.plotView->SetProperty, Dimensions=[position[2]-position[0], position[3]-position[1]], $
Location=[position[0], position[1]], Units=3
; Print it. May take a little time. Alert the user.
Widget_Control, Hourglass=1
info.thisPrinter->Draw, info.plotView
info.thisPrinter->NewDocument
Widget_Control, Hourglass=0
; Put things back the way you found them.
info.plotView->SetProperty, Location=[0,0], Dimensions=[0,0]
ENDIF
END
ENDCASE
; Put the info structure back.
Widget_Control, event.top, Set_UValue=info, /No_Copy
END
;-------------------------------------------------------------------
PRO XImage_Image_Colors, event
; This event handler changes color tables.
Widget_Control, event.top, Get_UValue=info, /No_Copy
; What kind of event is this?
thisEvent = Tag_Names(event, /Structure_Name)
CASE thisEvent OF
"WIDGET_BUTTON": BEGIN
TVLCT, info.r, info.g, info.b
XColors, Group_Leader=event.top, NotifyID=[event.id, event.top]
ENDCASE
"XCOLORS_LOAD": BEGIN
info.r = event.r
info.g = event.g
info.b = event.b
IF Obj_Valid(info.thisPalette) THEN info.thisPalette->SetProperty, $
Red=event.r, Green=event.g, Blue=event.b
ENDCASE
ENDCASE
; Draw the graphic display.
info.thisWindow->Draw, info.plotView
Widget_Control, event.top, Set_UValue=info, /No_Copy
END ;------------------------------------------------------------------------------
PRO XIMAGE_CLEANUP, id
; Come here when the widget dies. Free all the program
; objects, pointers, pixmaps, etc. and release memory.
Widget_Control, id, Get_UValue=info
IF N_Elements(info) NE 0 THEN BEGIN
Obj_Destroy, info.thisContainer
Ptr_Free, info.imagePtr
Ptr_Free, info.processPtr
ENDIF
END
;---------------------------------------------------------------------
PRO XImage_DrawWidget_Event, event
; This event handler handles draw widget events, including
; image value selection events.
Widget_Control, event.top, Get_UValue=info, /No_Copy
possibleEvents = ['DOWN', 'UP', 'MOTION', 'SCROLL', 'EXPOSE']
thisEvent = possibleEvents[event.type]
CASE thisEvent OF
'DOWN': Widget_Control, event.id, Draw_Motion_Events=1
'UP': Widget_Control, event.id, Draw_Motion_Events=0
'EXPOSE': info.thisWindow->Draw, info.plotView
ELSE:
ENDCASE
IF thisEvent NE 'EXPOSE' THEN BEGIN
; Calculate the image value at the current location. If 24-bit image, skip writing the value,
; since this make no sense for a 24-bit image.
hit = info.thisWindow->Pickdata(info.plotView, info.thisImage, [event.x, event.y], xyz)
xpt = Floor(xyz[0])
ypt = Floor(xyz[1])
IF xpt LT 0 OR xpt GT (info.xsize-1) OR ypt LT 0 OR ypt GT (info.ysize-1) THEN BEGIN
Widget_Control, info.xvalueID, Set_Value=-999
Widget_Control, info.yvalueID, Set_Value=-999
IF info.truecolor EQ 0 THEN $
Widget_Control, info.valueID, Set_Value='-9999.0'
ENDIF ELSE BEGIN
Widget_Control, info.xvalueID, Set_Value=xpt
Widget_Control, info.yvalueID, Set_Value=ypt
IF info.truecolor EQ 0 THEN $
Widget_Control, info.valueID, Set_Value=Float((*info.processPtr)[xpt, ypt])
ENDELSE
ENDIF
;Put the info structure back.
Widget_Control, event.top, Set_UValue=info, /No_Copy
END
;-------------------------------------------------------------------
PRO XImage_Resize, event
; This is main event handler for the TLB. It handles resize events.
Widget_Control, event.top, Get_UValue=info, /No_Copy
; Resize the draw widget.
info.thisWindow->SetProperty, Dimension=[event.x > 400, event.y-info.basesize]
; Keep the aspect ratio of the graphic?
IF info.keepAspect THEN BEGIN
; Get the new viewplane rectangle.
waspect = (event.y-info.basesize) / Float(event.x > 400)
IF waspect GE 1.0 THEN BEGIN
ylen = 1.0 * waspect
xlen = 1.0
ystart = (-ylen/2.0) + 0.5 ; Center it.
xstart = 0.0
ENDIF ELSE BEGIN
xlen = 1.0 / waspect
ylen = 1.0
xstart = (-xlen/2.0) + 0.5 ; Center it.
ystart = 0.0
ENDELSE
; Reset the viewplane rectangle.
info.plotView->SetProperty,Viewplane_Rect=[xstart, ystart, xlen, ylen]
ENDIF
; Redisplay the graphic.
info.thisWindow->Draw, info.plotView
;Put the info structure back.
Widget_Control, event.top, Set_UValue=info, /No_Copy
END
;---------------------------------------------------------------------
PRO XIMAGE, image, XRange=xrange, YRange=yrange, $
Keep_Aspect=keepAspect, XSize=wxsize, YSize=wysize, $
Colortable=colortable, XTitle=xtitle, YTitle=ytitle, $
Group_Leader=group, Title=plottitle, TrueColor=trueColor
; Check for parameters. If no parameters, load world elevation data.
IF N_Params() EQ 0 THEN BEGIN
filename = Filepath(SubDir=['examples', 'data'], 'worldelv.dat')
OpenR, lun, filename, /Get_LUN
image = BytArr(360,360)
yrange = [-90, 90]
xrange = [0, 360]
plottitle='World Elevation'
xtitle = 'Longitude'
ytitle='Latitude'
colortable = 33
ReadU, lun, image
Free_Lun, lun
ENDIF
; Get dimensions of image data. Set up INTERLEAVE variable.
s = SIZE(image)
IF s(0) LT 2 THEN Message, 'Must pass a 2D or 3D image data set.'
IF s(0) EQ 2 THEN BEGIN
xsize = s(1)
ysize = s(2)
interleave = 0
IF N_Elements(trueColor) EQ 0 THEN trueColor = 0
ENDIF
IF s(0) EQ 3 THEN BEGIN
sizes = [s(1), s(2), s(3)]
interleave = WHERE(sizes EQ 3)
interleave = interleave(0)
IF N_Elements(trueColor) EQ 0 THEN trueColor = 1
IF interleave LT 0 THEN $
Message, 'Image does not appear to be a 24-bit image. Returning...'
CASE interleave OF
0: BEGIN
xsize = s(2)
ysize = s(3)
END
1: BEGIN
xsize = s(1)
ysize = s(3)
END
2: BEGIN
xsize = s(1)
ysize = s(2)
END
ENDCASE
ENDIF
; Check for keyword parameters. Define default values if necessary.
IF N_Elements(xrange) EQ 0 THEN xrange = [0,xsize]
IF N_Elements(yrange) EQ 0 THEN yrange = [0,ysize]
IF N_Elements(wxsize) EQ 0 THEN wxsize = 400
IF N_Elements(wysize) EQ 0 THEN wysize = 400
IF N_Elements(xtitle) EQ 0 THEN xtitle = ''
IF N_Elements(ytitle) EQ 0 THEN ytitle = ''
IF N_Elements(plotTitle) EQ 0 THEN plotTitle=''
IF N_Elements(colortable) EQ 0 THEN colortable = 0
keepAspect = Keyword_Set(keepAspect)
; Calculate the aspect ratios (height/width) for the image
; and for the display window.
imageAspect = Float(ysize) / xsize
windowAspect = Float(wysize) / wxsize
; If this is an 8-bit image, we will need a color palette.
IF truecolor EQ 0 THEN BEGIN
thisPalette = Obj_New('IDLgrPalette')
thisPalette->LoadCT, colortable
thisPalette->GetProperty, Red=r, Blue=b, Green=g
ENDIF ELSE BEGIN
thisPalette = Obj_New()
TVLCT, r, g, b, /Get
ENDELSE
; Define other drawing colors.
antiqueWhite = [250, 235, 215]
navyBlue = [0, 0, 128]
firebrickRed = [178, 34, 34]
; Create the image object.
imagePtr = Ptr_New(image)
processPtr = Ptr_New(image)
thisImage = Obj_New('IDLgrImage', BytScl(*imagePtr), $
Dimensions=[xsize,ysize], Interleave=interleave, $
Palette=thisPalette)
; Create scaling parameters for the image. I get
; position coordinates for a normalized window from
; my XImage_Aspect function. Then use my FSC_Normalize
; function to create scaling factors for the image.
pos = XImage_Aspect(imageAspect, WindowAspect=windowAspect, Margin=0.125)
xs = FSC_Normalize([0,xsize], Position=[pos(0), pos(2)])
ys = FSC_Normalize([0,ysize], Position=[pos(1), pos(3)])
thisImage->SetProperty, XCoord_Conv=xs, YCoord_Conv=ys
; Note that XCoord_Conv and YCoord_Conv are broken in IDL 5.0
; for the image object, I must put the image in its own model
; and scale the model appropriately if I am running there.
; The code looks like this:
;imageModel = Obj_New('IDLgrModel')
;imageModel->Scale, (pos(2)-pos(0))/xsize, (pos(3)-pos(1))/ysize, 1
;imageModel->Translate, pos(0), pos(1), 1
;imageModel->Add, thisImage
; Set up font objects for the axes titles.
helvetica10pt = Obj_New('IDLgrFont', 'Helvetica', Size=12)
helvetica8pt = Obj_New('IDLgrFont', 'Helvetica', Size=10)
; Create title objects for the axes. Color them yellow.
xTitle = Obj_New('IDLgrText', xtitle, Recompute_Dimensions=1, Font=helvetica8pt)
yTitle = Obj_New('IDLgrText', ytitle, Recompute_Dimensions=1, Font=helvetica8pt)
; Create a plot title object. I want the title centered just
; above the upper X Axis.
plotTitle = Obj_New('IDLgrText', plotTitle, Color=NavyBlue, $
Location=[0.5, pos(3)+0.05, 0.0], Alignment=0.5, Font=helvetica10pt, $
Recompute_Dimensions=1)
; Set up scaling for the axes. Notice that we use the axis
; range here, not the size of the image, as before.
pos = XImage_Aspect(imageAspect, WindowAspect=windowAspect, Margin=0.125)
xs = FSC_Normalize(xrange, Position=[pos(0), pos(2)])
ys = FSC_Normalize(yrange, Position=[pos(1), pos(3)])
; Create the four axis objects (box axes). Make the titles
; with helvetica 10 point fonts.
xAxis1 = Obj_New("IDLgrAxis", 0, Color=firebrickRed, Ticklen=0.025, $
Minor=4, Range=xrange, /Exact, Title=xTitle, XCoord_Conv=xs, $
Location=[1000, pos(1), 0.125])
xAxis1->GetProperty, Ticktext=xAxisText
xAxisText->SetProperty, Font=helvetica8pt, Recompute_Dimensions=2
xAxis2 = Obj_New("IDLgrAxis", 0, Color=firebrickRed, Ticklen=0.025, $
Minor=4, /NoText, Range=xrange, TickDir=1, /Exact, XCoord_Conv=xs, $
Location=[1000, pos(3), 0.125])
yAxis1 = Obj_New("IDLgrAxis", 1, Color=firebrickRed, Ticklen=0.025, $
Minor=4, Title=ytitle, Range=yrange, /Exact, YCoord_conv=ys, $
Location=[pos(0) ,1000, 0.125])
yAxis1->GetProperty, Ticktext=yAxisText
yAxisText->SetProperty, Font=helvetica8pt, Recompute_Dimensions=2
yAxis2 = Obj_New("IDLgrAxis", 1, Color=firebrickRed, Ticklen=0.025, $
Minor=4, /NoText, Range=yrange, TickDir=1, /Exact, YCoord_conv=ys, $
Location=[pos(2), 1000, 0.125])
; Create a plot model and add axes, image, title to it.
plotModel = Obj_New('IDLgrModel', Select=1)
plotModel->Add, thisImage
plotModel->Add, xAxis1
plotModel->Add, xAxis2
plotModel->Add, yAxis1
plotModel->Add, yAxis2
plotModel->Add, plotTitle
; Create a plot view. Add the model to the view. Notice
; the view is created to give space around the region
; where the "action" in the plot takes place. The extra
; space has to be large enough to accomodate axis annotation.
viewRect = [0.0, 0.0, 1.0, 1.0]
plotView = Obj_New('IDLgrView', Viewplane_Rect=viewRect, $
Location=[0,0], Color=antiqueWhite)
plotView->Add, plotModel
; Create the widgets for this program.
tlb = Widget_Base(Title='Resizeable Image Example', $
MBar=menubase, TLB_Size_Events=1, Column=1, Base_Align_Center=1)
; Create the draw widget. RETAIN=0 is necessary to generate
; EXPOSE events.
drawID = Widget_Draw(tlb, XSize=wxsize, YSize=wysize, $
Graphics_Level=2, Expose_Events=1, Retain=0, $
Event_Pro='XImage_DrawWidget_Event', Button_Events=1)
; Create image value and location widgets.
bottomBase = Widget_Base(tlb, Colum=1, /Base_Align_Center)
labelBase = Widget_Base(bottomBase, Row=1)
dummy = Widget_Label(labelBase, Value='Click (and drag) inside image for Image Value')
valueBase = Widget_Base(bottomBase, Row=1)
xvalueID = CW_Field(valueBase, Title='X Location:', Value=-999, /Integer, XSize=6)
yvalueID = CW_Field(valueBase, Title=' Y Location:', Value=-999, /Integer, XSize=6)
IF trueColor THEN BEGIN
valueID = CW_Field(valueBase, Title=' Image Value:', Value='Not Available', XSize=12)
ENDIF ELSE BEGIN
valueID = CW_Field(valueBase, Title=' Image Value:', Value='-9999.0', XSize=12, /Float)
ENDELSE
; Create FILE menu buttons for printing and exiting.
filer = Widget_Button(menubase, Value='File', /Menu)
; Create OUTPUT menu buttons for formatted output files.
output = Widget_Button(filer, Value='Save As...', /Menu)
; Check for availability of GIF files.
thisVersion = Float(!Version.Release)
IF thisVersion LT 5.4 THEN haveGif = 1 ELSE haveGIF = 0
IF havegif THEN b = Widget_Button(output, Value='GIF File', $
UValue='GIF', Event_Pro='XImage_Output')
button = Widget_Button(output, Value='JPEG File', $
UValue='JPEG', Event_Pro='XImage_Output')
button = Widget_Button(output, Value='TIFF File', $
UValue='TIFF', Event_Pro='XImage_Output')
button = Widget_Button(output, Value='PNG File', $
UValue='PNG', Event_Pro='XImage_Output')
button = Widget_Button(output, Value='PICT File', $
UValue='PICT', Event_Pro='XImage_Output')
button = Widget_Button(output, Value='BMP File', $
UValue='BMP', Event_Pro='XImage_Output')
dummy = Widget_Button(filer, Value='Print', $
Event_Pro='XImage_Printing', UValue='PRINT')
dummy = Widget_Button(filer, Value='Print Setup', $
Event_Pro='XImage_Printing', UValue='SETUP')
dummy = Widget_Button(filer, /Separator, Value='Quit', $
Event_Pro='XImage_Exit')
IF trueColor EQ 0 THEN BEGIN
; Create COLORS menu buttons for changing colors.
colorID = Widget_Button(menubase, Value='Colors', /Menu)
; Image Colors
imagecolors = Widget_Button(colorID, Value='Image Colors...', $
Event_Pro='XImage_Image_Colors')
ENDIF
; Create IMAGE PROCESSING menu buttons.
processing = Widget_Button(menubase, Menu=1, $
Value='Processing')
edge = Widget_Button(processing, Menu=1, $
Value='Edge Enhancement')
dummy = Widget_Button(edge, Value='Sobel', UValue='SOBEL', $
Event_Pro='XImage_Processing')
dummy = Widget_Button(edge, Value='Roberts', UValue='ROBERTS', $
Event_Pro='XImage_Processing')
smoother = Widget_Button(processing, Menu=1, $
Value='Image Smoothing')
dummy = Widget_Button(smoother, Value='Boxcar', UValue='BOXCAR', $
Event_Pro='XImage_Processing')
dummy = Widget_Button(smoother, Value='Median', UValue='MEDIAN', $
Event_Pro='XImage_Processing')
dummy = Widget_Button(processing, Value='Original Image', $
Event_Pro='XImage_Processing', UValue='ORIGINAL')
; Zoom in and out buttons.
zoomit = Widget_Button(menubase, Value='Zoom')
zInButton = Widget_Button(zoomit, Value='Zoom In', $
Event_Pro='XImage_Zoom_Button_Event', UValue='ZOOM_IN')
zOutButton = Widget_Button(zoomit, Value='Zoom Out', $
Event_Pro='XImage_Zoom_Button_Event', UValue='ZOOM_OUT')
; Realize the widgets and get the window object.
Widget_Control, tlb, /Realize
Widget_Control, drawID, Get_Value=thisWindow
; Find out the size of the base below the image
; so you can keep it in the face of window resizing.
geom = Widget_Info(bottomBase, /Geometry)
basesize = geom.scr_ysize
; Load the palette into the window. This will cause the
; image to be output through the palette always, even
; when displayed on 24-bit displays.
thisWindow->SetProperty, Palette=thisPalette
; Draw the graphic in the window.
thisWindow->Draw, plotView
; Get a printer object for this graphic.
thisPrinter = Obj_New('IDLgrPrinter')
; Create a container object to hold all the other
; objects. This will make it easy to free all the
; objects when we are finished with the program.
; Make a container to hold all the objects you created.
thisContainer = Obj_New('IDL_Container')
thisContainer->Add, thisWindow
thisContainer->Add, plotView
thisContainer->Add, thisPrinter
thisContainer->Add, xTitle
thisContainer->Add, yTitle
thisContainer->Add, thisPalette
thisContainer->Add, helvetica10pt
thisContainer->Add, helvetica8pt
thisContainer->Add, xaxis1
thisContainer->Add, xaxis2
thisContainer->Add, yaxis1
thisContainer->Add, yaxis2
thisContainer->Add, plotTitle
s = Size(*imagePtr, /Dimensions)
; Create an info structure to hold program information.
info = { thisContainer:thisContainer, $ ; The container object.
thisPalette:thisPalette, $ ; The palette for INDEXED color.
thisWindow:thisWindow, $ ; The window object.
plotView:plotView, $ ; The view that will be rendered.
thisPrinter:thisPrinter, $ ; The printer object.
thisImage:thisImage, $ ; The image object.
processPtr:processPtr, $ ; The pointer to the processed image.
imagePtr:imagePtr, $ ; The pointer to the original image.
xsize:xsize, $ ; The X size of the image
ysize:ysize, $ ; The Y size of the image.
plotTitle:plotTitle, $ ; The plot title.
viewRect:viewRect, $ ; The original viewplane rectangle.
xAxis1:xAxis1, $ ; Bottom X axis.
xAxis2:xAxis2, $ ; Top X axis
yAxis1:yAxis1, $ ; Left Y axis.
yAxis2:yAxis2, $ ; Right Y axis.
r:r, $ ; The red color table values.
g:g, $ ; The green color table values.
b:b, $ ; The blue color table values.
antiqueWhite:antiqueWhite, $ ; The background color.
navyBlue:navyBlue, $ ; The axes color.
firebrickRed:firebrickRed, $ ; The annotation color.
truecolor:truecolor, $ ; A flag indicating a 24-bit image.
xvalueID:xvalueID, $ ; X location widget ID.
yvalueID:yvalueID, $ ; Y location widget ID.
valueID:valueID, $ ; Image value widget ID.
basesize:basesize, $ ; The height of the label base.
keepAspect:keepAspect, $ ; The image keep aspect flag.
drawID:drawID } ; The draw widget ID.
Widget_Control, tlb, Set_UValue=info, /No_Copy
XManager, 'ximage', tlb, Cleanup='XImage_Cleanup', $
Group_Leader=group, /No_Block, Event_Handler='XImage_Resize'
END