source: trunk/SRC/Picture/imdisp.pro

Last change on this file was 493, checked in by pinsard, 10 years ago

fix some typos in comments

  • Property svn:keywords set to Id
File size: 27.5 KB
Line 
1;+
2; @hidden
3;-
4FUNCTION imdisp_getpos, ASPECT, POSITION=POSITION, MARGIN=MARGIN
5;
6  compile_opt idl2, strictarrsubs
7;
8
9;- Compute a position vector given an aspect ratio (called by IMDISP_IMSIZE)
10
11;- Check arguments
12if (n_params() ne 1) then message, 'Usage: RESULT = IMDISP_GETPOS(ASPECT)'
13if (n_elements(aspect) eq 0) then message, 'ASPECT is undefined'
14
15;- Check keywords
16if (n_elements(position) eq 0) then position = [0.0, 0.0, 1.0, 1.0]
17if (n_elements(margin) eq 0) then margin = 0.1
18
19;- Get range limited aspect ratio and margin input values
20aspect_val = (float(aspect[0]) > 0.01) < 100.0
21margin_val = (float(margin[0]) > 0.0) < 0.495
22
23;- Compute aspect ratio of position vector in this window
24xsize = (position[2] - position[0]) * !d.x_vsize
25ysize = (position[3] - position[1]) * !d.y_vsize
26cur_aspect = ysize / xsize
27
28;- Compute aspect ratio of this window
29win_aspect = float(!d.y_vsize) / float(!d.x_vsize)
30
31;- Compute height and width in normalized units
32if (aspect_val ge cur_aspect) then begin
33  height = (position[3] - position[1]) - 2.0 * margin
34  width  = height * (win_aspect / aspect_val)
35endif else begin
36  width  = (position[2] - position[0]) - 2.0 * margin
37  height = width * (aspect_val / win_aspect)
38endelse
39
40;- Compute and return position vector
41xcenter = 0.5 * (position[0] + position[2])
42ycenter = 0.5 * (position[1] + position[3])
43x0 = xcenter - 0.5 * width
44y0 = ycenter - 0.5 * height
45x1 = xcenter + 0.5 * width
46y1 = ycenter + 0.5 * height
47return, [x0, y0, x1, y1]
48
49END
50;+
51; @hidden
52;-
53FUNCTION imdisp_imscale, IMAGE, RANGE=RANGE, BOTTOM=BOTTOM, NCOLORS=NCOLORS, $
54  NEGATIVE=NEGATIVE
55;
56  compile_opt idl2, strictarrsubs
57;
58
59;- Byte-scale an image (called by IMDISP)
60
61;- Check arguments
62if (n_params() ne 1) then message, 'Usage: RESULT = IMDISP_IMSCALE(IMAGE)'
63if (n_elements(image) eq 0) then message, 'Argument IMAGE is undefined'
64
65;- Check keywords
66if (n_elements(range) eq 0) then begin
67  min_value = min(image, max=max_value)
68  range = [min_value, max_value]
69endif
70if (n_elements(bottom) eq 0) then bottom = 0B
71if (n_elements(ncolors) eq 0) then ncolors = !d.table_size - bottom
72
73;- Compute the scaled image
74scaled = bytscl(image, min=range[0], max=range[1], top=(ncolors - 1))
75
76;- Create a negative image if required
77if keyword_set(negative) then scaled = byte(ncolors - 1) - scaled
78
79;- Return the scaled image in the correct color range
80return, scaled + byte(bottom)
81
82END
83;
84;+
85; @hidden
86;-
87FUNCTION imdisp_imregrid, DATA, NX, NY, INTERP=INTERP
88;
89  compile_opt idl2, strictarrsubs
90;
91
92;- Regrid a 2D array (called by IMDISP)
93
94;- Check arguments
95if (n_params() ne 3) then $
96  message, 'Usage: RESULT = IMDISP_IMREGRID(DATA, NX, NY)'
97if (n_elements(data) eq 0) then message, 'Argument DATA is undefined'
98result = size(data)
99ndims = result[0]
100dims = result[1:ndims]
101if (ndims ne 2) then message, 'Argument DATA must have 2 dimensions'
102if (n_elements(nx) eq 0) then message, 'Argument NX is undefined'
103if (n_elements(ny) eq 0) then message, 'Argument NY is undefined'
104if (nx lt 1) then message, 'NX must be 1 or greater'
105if (ny lt 1) then message, 'NY must be 1 or greater'
106
107;- Copy the array if the requested size is the same as the current size
108if (nx eq dims[0]) and (ny eq dims[1]) then begin
109  new = data
110  return, new
111endif
112
113;- Compute index arrays for bilinear interpolation
114xindex = (findgen(nx) + 0.5) * (dims[0] / float(nx)) - 0.5
115yindex = (findgen(ny) + 0.5) * (dims[1] / float(ny)) - 0.5
116
117;- Round the index arrays if nearest neighbor sampling is required
118if (keyword_set(interp) eq 0) then begin
119  xindex = round(xindex)
120  yindex = round(yindex)
121endif
122
123;- Return regridded array
124return, interpolate(data, xindex, yindex, /grid)
125
126END
127;
128;+
129;
130; @hidden
131;
132;-
133PRO imdisp_imsize, IMAGE, X0, Y0, XSIZE, YSIZE, ASPECT=ASPECT, $
134  POSITION=POSITION, MARGIN=MARGIN
135;
136  compile_opt idl2, strictarrsubs
137;
138
139;- Compute the size and offset for an image (called by IMDISP)
140
141;- Check arguments
142if (n_params() ne 5) then $
143  message, 'Usage: IMDISP_IMSIZE, IMAGE, X0, Y0, XSIZE, YSIZE'
144if (n_elements(image) eq 0) then $
145  message, 'Argument IMAGE is undefined'
146if (n_elements(position) eq 0) then position = [0.0, 0.0, 1.0, 1.0]
147if (n_elements(position) ne 4) then $
148  message, 'POSITION must be a 4 elements vector'
149if (n_elements(margin) eq 0) then margin = 0.1
150if (n_elements(margin) ne 1) then $
151  message, 'MARGIN must be a scalar'
152
153;- Get image dimensions
154result = size(image)
155ndims = result[0]
156if (ndims ne 2) then message, 'IMAGE must be a 2D array'
157dims = result[1 : ndims]
158
159;- Get aspect ratio for image
160if (n_elements(aspect) eq 0) then $
161  aspect = float(dims[1]) / float(dims[0])
162if (n_elements(aspect) ne 1) then $
163  message, 'ASPECT must be a scalar'
164
165;- Check output parameters
166if (arg_present(x0) ne 1) then message, 'Argument XO cannot be set'
167if (arg_present(y0) ne 1) then message, 'Argument YO cannot be set'
168if (arg_present(xsize) ne 1) then message, 'Argument XSIZE cannot be set'
169if (arg_present(ysize) ne 1) then message, 'Argument YSIZE cannot be set'
170
171;- Get approximate image position
172position = imdisp_getpos(aspect, position=position, margin=margin)
173
174;- Compute lower left position of image (device units)
175x0 = round(position[0] * !d.x_vsize) > 0L
176y0 = round(position[1] * !d.y_vsize) > 0L
177
178;- Compute size of image (device units)
179xsize = round((position[2] - position[0]) * !d.x_vsize) > 2L
180ysize = round((position[3] - position[1]) * !d.y_vsize) > 2L
181
182;- Recompute the image position based on actual image size
183position = fltarr(4)
184position[0] = x0 / float(!d.x_vsize)
185position[1] = y0 / float(!d.y_vsize)
186position[2] = (x0 + xsize) / float(!d.x_vsize)
187position[3] = (y0 + ysize) / float(!d.y_vsize)
188
189END
190;
191;+
192;
193; @file_comments
194;    Display an image on the current graphics device.
195;    IMDISP is an advanced replacement for <proidl>TV</proidl> and
196;    <proidl>TVSCL</proidl>.
197;
198;    - Supports WIN, MAC, X, CGM, PCL, PRINTER, PS, and Z graphics devices,
199;    - Image is automatically byte-scaled (can be disabled),
200;    - Custom byte-scaling of Pseudo color images via the RANGE keyword,
201;    - Pseudo (indexed) color and True color images are handled automatically,
202;    - 8-bit and 24-bit graphics devices  are handled automatically,
203;    - Decomposed color settings are handled automatically,
204;    - Image is automatically sized to fit the display (can be disabled),
205;    - The !P.MULTI system variable is honored for multiple image display,
206;    - Image can be positioned via the POSITION keyword,
207;    - Color table splitting via the BOTTOM and NCOLORS keywords,
208;    - Image aspect ratio customization via the ASPECT keyword,
209;    - Resized images can be resampled (default) or interpolated,
210;    - Top down image display via the ORDER keyword (!ORDER is ignored),
211;    - Selectable display channel (R/G/B) via the CHANNEL keyword,
212;    - Background can be set to a specified color via the BACKGROUND keyword,
213;    - Screen can be erased prior to image display via the ERASE keyword,
214;    - Plot axes can be drawn on the image via the AXIS keyword,
215;    - Photographic negative images can be displayed via the NEGATIVE keyword.
216;
217; @categories
218; Picture
219;
220; @param IMAGE {in}{required}
221; Array containing image data.
222; Pseudo (indexed) color images must have 2 dimensions.
223; True color images must have 3 dimensions, in either
224; [3, NX, NY], [NX, 3, NY], or [NX, NY, 3] form.
225;
226; @keyword RANGE {type=vector}{default=min and max array values}
227; For Pseudo Color images only, a vector with two elements
228; specifying the minimum and maximum values of the image
229; array to be considered when the image is byte-scaled
230; This keyword is ignored for True Color images,
231; or if the NOSCALE keyword is set.
232;
233; @keyword BOTTOM {default=0}
234; Bottom value in the color table to be used
235; for the byte-scaled image.
236; This keyword is ignored if the NOSCALE keyword is set.
237;
238; @keyword NCOLORS {default=!D.TABLE_SIZE - BOTTOM}
239; Number of colors in the color table to be used
240; for the byte-scaled image
241; This keyword is ignored if the NOSCALE keyword is set.
242;
243; @keyword MARGIN {default=0.1 or 0.025 if !P.MULTI is set to display multiple images}
244; A scalar value specifying the margin to be maintained
245; around the image in normal coordinates
246;
247; @keyword INTERP {default=nearest neighbor sampling}
248; If set, the resized image will be interpolated using
249; bilinear interpolation
250;
251; @keyword DITHER {default=no dithering}
252; If set, true color images will be dithered when displayed
253; on an 8-bit graphics device
254;
255; @keyword ASPECT {default=maintain native aspect ratio}
256; A scalar value specifying the aspect ratio (height/width)
257; for the displayed image
258;
259; @keyword POSITION {default= [0.0,0.0,1.0,1.0]}
260; On input, a 4-element vector specifying the position
261; of the displayed image in the form [X0,Y0,X1,Y1] in
262; in normal coordinates
263; See the examples below to display an image where only the
264; offset and size are known (e.g. MAP_IMAGE output).
265;
266; @keyword OUT_POS
267; On output, a 4-element vector specifying the position
268; actually used to display the image.
269;
270; @keyword NOSCALE {default=to byte-scale the image}
271; If set, the image will not be byte-scaled.
272;
273; @keyword NORESIZE {default=To resize the image to fit the display}
274; If set, the image will not be resized.
275;
276; @keyword ORDER {default=To display the image from the bottom up}
277; If set, the image is displayed from the top down
278; Note that the system variable !ORDER is always ignored.
279;
280; @keyword USEPOS {default=To honor ASPECT and MARGIN when POSITION vector is supplied}
281; If set, the image will be sized to exactly fit a supplied
282; POSITION vector, over-riding ASPECT and MARGIN.
283;
284; @keyword CHANNEL
285; Display channel (Red, Green, or Blue) to be written.
286; 0 => All channels (the default)
287; 1 => Red channel
288; 2 => Green channel
289; 3 => Blue channel
290; This keyword is only recognized by graphics devices which
291; support 24-bit decomposed color (WIN, MAC, X). It is ignored
292; by all other graphics devices. However True color (RGB)
293; images can be displayed on any device supported by IMDISP.
294;
295; @keyword BACKGROUND
296; If set to a positive integer, the background will be filled
297; with the color defined by BACKGROUND.
298;
299; @keyword ERASE
300; If set, the screen contents will be erased. Note that if
301; !P.MULTI is set to display multiple images, the screen is
302; always erased when the first image is displayed.
303;
304; @keyword AXIS
305; If set, plot axes will be drawn on the image. The default
306; x and y axis ranges are determined by the size of the image.
307; When the AXIS keyword is set, IMDISP accepts any keywords
308; supported by PLOT (e.g. TITLE, COLOR, CHARSIZE etc.).
309;
310; @keyword NEGATIVE
311; If set, a photographic negative of the image is displayed.
312; The values of BOTTOM and NCOLORS are honored. This keyword
313; allows True color images scanned from color negatives to be
314; displayed. It also allows Pseudo color images to be displayed
315; as negatives without reversing the color table. This keyword
316; is ignored if the NOSCALE keyword is set.
317;
318; @restrictions
319; The image is displayed on the current graphics device.
320;
321; @restrictions
322; Requires IDL 5.0 or higher (square bracket array syntax).
323;
324; @examples
325;
326;;- Load test data
327;
328; openr, lun, filepath('ctscan.dat', subdir='examples/data'), /get_lun
329;ctscan = bytarr(256, 256)
330;readu, lun, ctscan
331;free_lun, lun
332;openr, lun, filepath('hurric.dat', subdir='examples/data'), /get_lun
333;hurric = bytarr(440, 330)
334;readu, lun, hurric
335;free_lun, lun
336;read_jpeg, filepath('rose.jpg', subdir='examples/data'), rose
337;help, ctscan, hurric, rose
338;
339;;- Display single images
340;
341;!p.multi = 0
342;loadct, 0
343;imdisp, hurric, /erase
344;wait, 3.0
345;imdisp, rose, /interp, /erase
346;wait, 3.0
347;
348;;- Display multiple images without color table splitting
349;;- (works on 24-bit displays only; top 2 images are garbled on 8-bit displays)
350;
351;!p.multi = [0, 1, 3, 0, 0]
352;loadct, 0
353;imdisp, ctscan, margin=0.02
354;loadct, 13
355;imdisp, hurric, margin=0.02
356;imdisp, rose, margin=0.02
357;wait, 3.0
358;
359;;- Display multiple images with color table splitting
360;;- (works on 8-bit or 24-bit displays)
361;
362;!p.multi = [0, 1, 3, 0, 0]
363;loadct, 0, ncolors=64, bottom=0
364;imdisp, ctscan, margin=0.02, ncolors=64, bottom=0
365;loadct, 13, ncolors=64, bottom=64
366;imdisp, hurric, margin=0.02, ncolors=64, bottom=64
367;imdisp, rose, margin=0.02, ncolors=64, bottom=128
368;wait, 3.0
369;
370;;- Display an image at a specific position, over-riding aspect and margin
371;
372;!p.multi = 0
373;loadct, 0
374;imdisp, hurric, position=[0.0, 0.0, 1.0, 0.5], /usepos, /erase
375;wait, 3.0
376;
377;;- Display an image with axis overlay
378;
379;!p.multi = 0
380;loadct, 0
381;imdisp, rose, /axis, /erase
382;wait, 3.0
383;
384;;- Display an image with contour plot overlay
385;
386;!p.multi = 0
387;loadct, 0
388;imdisp, hurric, out_pos=out_pos, /erase
389;contour, smooth(hurric, 10, /edge), /noerase, position=out_pos, $
390;  xstyle=1, ystyle=1, levels=findgen(5)*40.0, /follow
391;wait, 3.0
392;
393;;- Display a small image with correct resizing
394;
395;!p.multi = 0
396;loadct, 0
397;data = (dist(8))[1:7, 1:7]
398;imdisp, data, /erase
399;wait, 3.0
400;imdisp, data, /interp
401;wait, 3.0
402;
403;;- Display a true color image without and with interpolation
404;
405;!p.multi = 0
406;imdisp, rose, /erase
407;wait, 3.0
408;imdisp, rose, /interp
409;wait, 3.0
410;
411;;- Display a true color image as a photographic negative
412;
413;imdisp, rose, /negative, /erase
414;wait, 3.0
415;
416;;- Display a true color image on PostScript output
417;;- (note that color table is handled automatically)
418;
419;current_device = !d.name
420;set_plot, 'PS'
421;device, /color, bits_per_pixel=8, filename='imdisp_true.ps'
422;imdisp, rose, /axis, title='PostScript True Color Output'
423;device, /close
424;set_plot, current_device
425;
426;;- Display a pseudo color image on PostScript output
427;
428;current_device = !d.name
429;set_plot, 'PS'
430;device, /color, bits_per_pixel=8, filename='imdisp_pseudo.ps'
431;loadct, 0
432;imdisp, hurric, /axis, title='PostScript Pseudo Color Output'
433;device, /close
434;set_plot, current_device
435;
436;;- Display an image where only the offset and size are known
437;
438;;- Read world elevation data
439;file = filepath('worldelv.dat', subdir='examples/data')
440;openr, lun, file, /get_lun
441;data = bytarr(360, 360)
442;readu, lun, data
443;free_lun, lun
444;;- Reorganize array so it spans 180W to 180E
445;world = data
446;world[0:179, *] = data[180:*, *]
447;world[180:*, *] = data[0:179, *]
448;;- Create remapped image
449;map_set, /orthographic, /isotropic, /noborder
450;remap = map_image(world, x0, y0, xsize, ysize, compress=1)
451;;- Convert offset and size to position vector
452;pos = fltarr(4)
453;pos[0] = x0 / float(!d.x_vsize)
454;pos[1] = y0 / float(!d.y_vsize)
455;pos[2] = (x0 + xsize) / float(!d.x_vsize)
456;pos[3] = (y0 + ysize) / float(!d.y_vsize)
457;;- Display the image
458;loadct, 0
459;imdisp, remap, pos=pos, /usepos
460;map_continents
461;map_grid
462;
463; @history
464; Liam.Gumley\@ssec.wisc.edu
465; <a href="http://cimss.ssec.wisc.edu/~gumley"/>
466;
467; Copyright (C) 1999, 2000 Liam E. Gumley
468;
469; This program is free software; you can redistribute it and/or
470; modify it under the terms of the GNU General Public License
471; as published by the Free Software Foundation; either version 2
472; of the License, or (at your option) any later version.
473;
474; This program is distributed in the hope that it will be useful,
475; but WITHOUT ANY WARRANTY; without even the implied warranty of
476; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
477; GNU General Public License for more details.
478;
479; You should have received a copy of the GNU General Public License
480; along with this program; if not, write to the Free Software
481; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
482;
483; @version
484; $Id$
485;
486;-
487PRO imdisp, IMAGE, RANGE=RANGE, BOTTOM=BOTTOM, NCOLORS=NCOLORS, $
488  MARGIN=MARGIN, INTERP=INTERP, DITHER=DITHER, ASPECT=ASPECT, $
489  POSITION=POSITION, OUT_POS=OUT_POS, NOSCALE=NOSCALE, NORESIZE=NORESIZE, $
490  ORDER=ORDER, USEPOS=USEPOS, CHANNEL=CHANNEL, $
491  BACKGROUND=BACKGROUND, ERASE=ERASE, $
492  AXIS=AXIS, NEGATIVE=NEGATIVE, _EXTRA=EXTRA_KEYWORDS
493;
494  compile_opt idl2, strictarrsubs
495;
496
497rcs_id = '$Id$'
498
499;-------------------------------------------------------------------------------
500;- CHECK INPUT
501;-------------------------------------------------------------------------------
502
503;- Check arguments
504if (n_params() ne 1) then message, 'Usage: IMDISP, IMAGE'
505if (n_elements(image) eq 0) then message, 'Argument IMAGE is undefined'
506if (max(!p.multi) eq 0) then begin
507  if (n_elements(margin) eq 0) then begin
508    if (n_elements(position) eq 4) then margin = 0.0 else margin = 0.1
509  endif
510endif else begin
511  if (n_elements(margin) eq 0) then margin = 0.025
512endelse
513if (n_elements(order) eq 0) then order = 0
514if (n_elements(channel) eq 0) then channel = 0
515
516;- Check position vector
517if (n_elements(position) gt 0) then begin
518  if (n_elements(position) ne 4) then $
519    message, 'POSITION must be a 4 element vector of the form [X0, Y0, X1, Y1]'
520  if (position[0] lt 0.0) then message, 'POSITION[0] must be GE 0.0'
521  if (position[1] lt 0.0) then message, 'POSITION[1] must be GE 0.0'
522  if (position[2] gt 1.0) then message, 'POSITION[2] must be LE 1.0'
523  if (position[3] gt 1.0) then message, 'POSITION[3] must be LE 1.0'
524  if (position[0] ge position[2]) then $
525    message, 'POSITION[0] must be LT POSITION[2]'
526  if (position[1] ge position[3]) then $
527    message, 'POSITION[1] must be LT POSITION[3]'
528endif
529
530;- Check the image dimensions
531result = size(image)
532ndims = result[0]
533if (ndims lt 2) or (ndims gt 3) then $
534  message, 'IMAGE must be a Pseudo Color (2D) or True Color (3D) image array'
535dims = result[1:ndims]
536
537;- Check that 3D image array is in valid true color format
538true = 0
539if (ndims eq 3) then begin
540  index = where(dims eq 3L, count)
541  if (count eq 0) then $
542    message, 'True Color dimensions must be [3,NX,NY], [NX,3,NY], or [NX,NY,3]'
543  true = 1
544  truedim = index[0]
545endif
546
547;- Check scaling range for pseudo color images
548if (true eq 0) then begin
549  if (n_elements(range) eq 0) then begin
550    min_value = min(image, max=max_value)
551    range = [min_value, max_value]
552  endif
553  if (n_elements(range) ne 2) then $
554    message, 'RANGE keyword must be a 2-element vector'
555endif else begin
556  if (n_elements(range) gt 0) then $
557    message, 'RANGE keyword is not used for True Color images', /continue
558endelse
559
560;- Check for supported graphics devices
561names = ['WIN', 'MAC', 'X', 'CGM', 'PCL', 'PRINTER', 'PS', 'Z']
562result = where((!d.name eq names), count)
563if (count eq 0) then message, 'Graphics device is not supported'
564
565;- Get color table information
566if ((!d.flags and 256) ne 0) and (!d.window lt 0) then begin
567  window, /free, /pixmap
568  wdelete, !d.window
569endif
570if (n_elements(bottom) eq 0) then bottom = 0
571if (n_elements(ncolors) eq 0) then ncolors = !d.table_size - bottom
572
573;- Get IDL version number
574version = float(!version.release)
575
576;- Check for IDL 5.2 or higher if printer device is selected
577if (version lt 5.2) and (!d.name eq 'PRINTER') then $
578  message, 'IDL 5.2 or higher is required for PRINTER device support'
579
580;-------------------------------------------------------------------------------
581;- GET RED, GREEN, AND BLUE COMPONENTS OF TRUE COLOR IMAGE
582;-------------------------------------------------------------------------------
583
584if (true eq 1) then begin
585    case truedim of
586      0 : begin
587            red = image[0, *, *]
588            grn = image[1, *, *]
589            blu = image[2, *, *]
590      end
591      1 : begin
592            red = image[*, 0, *]
593            grn = image[*, 1, *]
594            blu = image[*, 2, *]
595      end
596      2 : begin
597            red = image[*, *, 0]
598            grn = image[*, *, 1]
599            blu = image[*, *, 2]
600      end
601  endcase
602  red = reform(red, /overwrite)
603  grn = reform(grn, /overwrite)
604  blu = reform(blu, /overwrite)
605endif
606
607;-------------------------------------------------------------------------------
608;- COMPUTE POSITION FOR IMAGE
609;-------------------------------------------------------------------------------
610
611;- Save first element of !p.multi
612multi_first = !p.multi[0]
613
614;- Establish image position if not defined
615if (n_elements(position) eq 0) then begin
616  if (max(!p.multi) eq 0) then begin
617    position = [0.0, 0.0, 1.0, 1.0]
618  endif else begin
619    plot, [0], /nodata, xstyle=4, ystyle=4, xmargin=[0, 0], ymargin=[0, 0]
620    position = [!x.window[0], !y.window[0], !x.window[1], !y.window[1]]
621  endelse
622endif
623
624;- Erase and fill the background if required
625if (multi_first eq 0) then begin
626  if keyword_set(erase) then erase
627  if (n_elements(background) gt 0) then begin
628    polyfill, [-0.01,  1.01,  1.01, -0.01, -0.01], $
629      [-0.01, -0.01,  1.01,  1.01, -0.01], /normal, color=background[0]
630  endif
631endif
632
633;- Compute image aspect ratio if not defined
634if (n_elements(aspect) eq 0) then begin
635  case true of
636    0 : result = size(image)
637    1 : result = size(red)
638  endcase
639  dims = result[1:2]
640  aspect = float(dims[1]) / float(dims[0])
641endif
642
643;- Save image xrange and yrange for axis overlays
644xrange = [0, dims[0]]
645yrange = [0, dims[1]]
646if (order eq 1) then yrange = reverse(yrange)
647
648;- Set the aspect ratio and margin to fill the position window if requested
649if keyword_set(usepos) then begin
650  xpos_size = float(!d.x_vsize) * (position[2] - position[0])
651  ypos_size = float(!d.y_vsize) * (position[3] - position[1])
652  aspect_value = ypos_size / xpos_size
653  margin_value = 0.0
654endif else begin
655  aspect_value = aspect
656  margin_value = margin
657endelse
658
659;- Compute size of displayed image and save output position
660pos = position
661case true of
662  0 : imdisp_imsize, image, x0, y0, xsize, ysize, position=pos, $
663        aspect=aspect_value, margin=margin_value
664  1 : imdisp_imsize,   red, x0, y0, xsize, ysize, position=pos, $
665        aspect=aspect_value, margin=margin_value
666endcase
667out_pos = pos
668
669;-------------------------------------------------------------------------------
670;- BYTE-SCALE THE IMAGE IF REQUIRED
671;-------------------------------------------------------------------------------
672
673;- Choose whether to scale the image or not
674if (keyword_set(noscale) eq 0) then begin
675
676  ;- Scale the image
677  case true of
678    0 : scaled = imdisp_imscale(image, bottom=bottom, ncolors=ncolors, $
679          range=range, negative=keyword_set(negative))
680    1 : begin
681          scaled_dims = (size(red))[1:2]
682          scaled = bytarr(scaled_dims[0], scaled_dims[1], 3)
683          scaled[0, 0, 0] = imdisp_imscale(red, bottom=0, ncolors=256, $
684            negative=keyword_set(negative))
685          scaled[0, 0, 1] = imdisp_imscale(grn, bottom=0, ncolors=256, $
686            negative=keyword_set(negative))
687          scaled[0, 0, 2] = imdisp_imscale(blu, bottom=0, ncolors=256, $
688            negative=keyword_set(negative))
689        end
690  endcase
691
692endif else begin
693
694  ;- Don't scale the image
695  case true of
696    0 : scaled = image
697    1 : begin
698          scaled_dims = (size(red))[1:2]
699          scaled = replicate(red[0], scaled_dims[0], scaled_dims[1], 3)
700          scaled[0, 0, 0] = red
701          scaled[0, 0, 1] = grn
702          scaled[0, 0, 2] = blu
703        end
704  endcase
705
706endelse
707
708;-------------------------------------------------------------------------------
709;- DISPLAY IMAGE ON PRINTER DEVICE
710;-------------------------------------------------------------------------------
711
712if (!d.name eq 'PRINTER') then begin
713
714  ;- Display the image
715  case true of
716    0 : begin
717          device, /index_color
718          tv, scaled, x0, y0, xsize=xsize, ysize=ysize, order=order
719        end
720    1 : begin
721          device, /true_color
722          tv, scaled, x0, y0, xsize=xsize, ysize=ysize, order=order, true=3
723        end
724  endcase
725
726  ;- Draw axes if required
727  if keyword_set(axis) then $
728    plot, [0], /nodata, /noerase, position=out_pos, $
729      xrange=xrange, xstyle=1, yrange=yrange, ystyle=1, $
730      _extra=extra_keywords
731
732  ;- Return to caller
733  return
734
735endif
736
737;-------------------------------------------------------------------------------
738;- DISPLAY IMAGE ON GRAPHICS DEVICES WHICH HAVE SCALABLE PIXELS
739;-------------------------------------------------------------------------------
740
741if ((!d.flags and 1) ne 0) then begin
742
743  ;- Display the image
744  case true of
745    0 : tv, scaled, x0, y0, xsize=xsize, ysize=ysize, order=order
746    1 : begin
747          tvlct, r, g, b, /get
748          loadct, 0, /silent
749          tv, scaled, x0, y0, xsize=xsize, ysize=ysize, order=order, true=3
750          tvlct, r, g, b
751        end
752  endcase
753
754  ;- Draw axes if required
755  if keyword_set(axis) then $
756    plot, [0], /nodata, /noerase, position=out_pos, $
757      xrange=xrange, xstyle=1, yrange=yrange, ystyle=1, $
758      _extra=extra_keywords
759
760  ;- Return to caller
761  return
762
763endif
764
765;-------------------------------------------------------------------------------
766;- RESIZE THE IMAGE
767;-------------------------------------------------------------------------------
768
769;- Resize the image
770if (keyword_set(noresize) eq 0) then begin
771  if (true eq 0) then begin
772    resized = imdisp_imregrid(scaled, xsize, ysize, interp=keyword_set(interp))
773  endif else begin
774    resized = replicate(scaled[0], xsize, ysize, 3)
775    resized[0, 0, 0] = imdisp_imregrid(reform(scaled[*, *, 0]), xsize, ysize, $
776      interp=keyword_set(interp))
777    resized[0, 0, 1] = imdisp_imregrid(reform(scaled[*, *, 1]), xsize, ysize, $
778      interp=keyword_set(interp))
779    resized[0, 0, 2] = imdisp_imregrid(reform(scaled[*, *, 2]), xsize, ysize, $
780      interp=keyword_set(interp))
781  endelse
782endif else begin
783  resized = temporary(scaled)
784  x0 = 0
785  y0 = 0
786endelse
787
788;-------------------------------------------------------------------------------
789;- GET BIT DEPTH FOR THIS DISPLAY
790;-------------------------------------------------------------------------------
791
792;- If this device supports windows, make sure a window has been opened
793if (!d.flags and 256) ne 0 then begin
794  if (!d.window lt 0) then begin
795    window, /free, /pixmap
796    wdelete, !d.window
797  endif
798endif
799
800;- Set default display depth
801depth = 8
802
803;- Get actual bit depth on supported displays
804if (!d.name eq 'WIN') or (!d.name eq 'MAC') or (!d.name eq 'X') then begin
805  if (version ge 5.1) then begin
806    device, get_visual_depth=depth
807  endif else begin
808    if (!d.n_colors gt 256) then depth = 24
809  endelse
810endif
811
812;-------------------------------------------------------------------------------
813;- SELECT DECOMPOSED COLOR MODE (ON OR OFF) FOR 24-BIT DISPLAYS
814;-------------------------------------------------------------------------------
815
816if (!d.name eq 'WIN') or (!d.name eq 'MAC') or (!d.name eq 'X') then begin
817  if (depth gt 8) then begin
818    if (version ge 5.2) then device, get_decomposed=entry_decomposed else $
819      entry_decomposed = 0
820    if (true eq 1) or (channel gt 0) then device, decomposed=1 else $
821      device, decomposed=0
822  endif
823endif
824
825;-------------------------------------------------------------------------------
826;- DISPLAY THE IMAGE
827;-------------------------------------------------------------------------------
828
829;- If the display is 8-bit and the image is true color,
830;- convert image from true color to indexed color
831if (depth le 8) and (true eq 1) then begin
832  resized = color_quan(temporary(resized), 3, r, g, b, $
833    colors=ncolors, dither=keyword_set(dither)) + byte(bottom)
834  tvlct, r, g, b, bottom
835  true = 0
836endif
837
838;- Set channel value for supported devices
839if (!d.name eq 'WIN') or (!d.name eq 'MAC') or (!d.name eq 'X') then begin
840  channel_value = channel
841endif else begin
842  channel_value = 0
843endelse
844
845;- Display the image
846case true of
847  0 : tv, resized, x0, y0, order=order, channel=channel_value
848  1 : tv, resized, x0, y0, order=order, true=3
849endcase
850
851;-------------------------------------------------------------------------------
852;- RESTORE THE DECOMPOSED COLOR MODE FOR 24-BIT DISPLAYS
853;-------------------------------------------------------------------------------
854
855if ((!d.name eq 'WIN') or (!d.name eq 'MAC') or (!d.name eq 'X')) and $
856  (depth gt 8) then begin
857  device, decomposed=entry_decomposed
858  if (!d.name eq 'MAC') then tv, [0], -1, -1
859endif
860
861;-------------------------------------------------------------------------------
862;- DRAW AXES IF REQUIRED
863;-------------------------------------------------------------------------------
864
865if keyword_set(axis) then $
866  plot, [0], /nodata, /noerase, position=out_pos, $
867    xrange=xrange, xstyle=1, yrange=yrange, ystyle=1, $
868    _extra=extra_keywords
869
870END
Note: See TracBrowser for help on using the repository browser.