; docformat = 'rst' ; ; NAME: ; cgImageInfo ; ; PURPOSE: ; The purpose of this program is allow interactive inquiry of image ; position and values for images displayed with cgImage. ; After a call to cgImage, cgImageInfo can be called and the user ; can use the cursor to click in the image display window. If the user clicks ; inside the image, the image location and value will be printed out in the ; user's IDL console window. ; ;******************************************************************************************; ; ; ; Copyright (c) 2011, 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. ; ;******************************************************************************************; ; ;+ ; The purpose of this program is allow interactive inquiry of image ; position and values for images displayed with cgImage. ; After a call to cgImage, cgImageInfo can be called and the user ; can use the cursor to click in the image display window. If the user clicks ; inside the image, the image location and value will be printed out in the ; user's IDL console window. The cgImageInfo program blocks the IDL command ; line until the RIGHT mouse button is clicked in the image display window. ; ; This cgImageInfo program is designed to work for the last image displayed with cgImage ; on a Windows or X device. Precautions are taken to help you avoid shooting ; yourself in the foot, but I can't anticipate every action a user might take at the ; IDL command line. Pay particular attention to exiting the program with the RIGHT mouse ; button before you close or kill the current graphics window. Failure to do so will ; put you into a very strange and precarious state from which no rescue is possible. ; You might want to consider using the Catalyst Program `IMGWIN ` ; as an alternative to cgImageInfo. ; ; :Categories: ; Graphics ; ; :Params: ; image: in, required, ; A 2D or 3D image array. Values will be returned from this image. ; In versions of IDL < 8.0, it is possible to use a HASH object of ; keys/images where this program will describe the value for each of ; the images in the HASH object. ; position: in, optional, type=float ; A four-element floating array giving the position of the image in ; the display window. If not provided, the image position will be ; retrieved from the last image position used with cgImage. ; ; :Examples: ; To display an image with axes and then inquire about it:: ; ; filename = FILEPATH(SUBDIR=['examples','data'], 'worldelv.dat') ; image = BYTARR(360,360) ; OPENR, lun, filename, /GET_LUN ; READU, lun, image ; FREE_LUN, lun ; ; thisPosition = [0.1, 0.1, 0.9, 0.9] ; cgImage, image, /KEEP_ASPECT, POSITION=thisPosition, /AXES ; cgImageInfo, image ; ; :Author: ; FANNING SOFTWARE CONSULTING:: ; David W. Fanning ; 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 ; ; :History: ; Change History:: ; Written by: David W Fanning, 16 March 2008. ; Added ability to specify position directly in call. 20 March 2008. DWF ; Changed cursor operation to conform with expected differences ; between Windows and UNIX. 20 March 2008, DWF. ; Slightly modified screen directions. 16 November 2010. DWF. ; Modified so that multiple images/grids can be described 18 May 2011. MHS ; ; :Copyright: ; Copyright (c) 2008-2011, Fanning Software Consulting, Inc. ;- PRO cgImageInfo, image, position COMPILE_OPT idl2 ; Error Handling. CATCH, theError IF theError NE 0 THEN BEGIN CATCH, /CANCEL void = cgErrorMsg() ; Set the cursor back to original shape. IF !D.Name EQ 'WIN' THEN BEGIN Device, /CURSOR_ORIGINAL ENDIF ELSE BEGIN Device, CURSOR_STANDARD=30 ENDELSE RETURN ENDIF ; Set up a common block to access cgImage informaton. COMMON FSC_$CGIMAGE, _cgimage_xsize, _cgimage_ysize, $ _cgimage_winxsize, _cgimage_winysize, $ _cgimage_position, _cgimage_winID, $ _cgimage_current ;; First check to see if we're using a HASH as input for the variable image. hsh = '' IF total( obj_valid( image ) EQ 1 ) && obj_isa( image, 'HASH' ) THEN BEGIN ;; If so, we need to pull out the first image from the hash so that all of the ;; information can be set up properly before the user selects data from the ;; displayed image hsh = image IF n_elements( hsh ) EQ 0 THEN Message, 'Must supply a hash of names/images to examine.' ;; keys = hsh -> keys( ) image = hsh[ keys[ 0 ] ] ;; check that each image in the hash has same dimensions. void = Image_Dimensions( image, xsize = first_xsize, ysize = first_ysize ) FOR k = 1, n_elements( keys ) - 1 DO BEGIN img = hsh[ keys[ k ] ] void = Image_Dimensions( img, xsize = xsize, ysize = ysize ) IF xsize NE first_xsize OR ysize NE first_ysize THEN $ Message, 'Each Image must have same X & Y dimensions' ENDFOR ENDIF ; Check to see if we can proceed. First see if we have an image. IF N_Elements(image) EQ 0 THEN Message, 'Must supply image for reporting values.' ; Only 2D and 24-bit images allowed. ndims = Size(image, /N_DIMENSIONS) IF ndims LT 2 OR ndims GT 3 THEN Message, 'Image must be 2D or 3D (True-Color).' s = Size(image, /Dimensions) ; Does this device support windows? IF (!D.FLAGS AND 256) EQ 0 THEN Message, 'cgImageInfo only works on devices that support windows.' ; Has a call to cgImage preceeded this call? IF _cgimage_current EQ 0 THEN Message, 'Must call cgImage prior to calling cgImageInfo.' ; Is the image window still open? Device, WINDOW_STATE=theWindows IF theWindows[_cgimage_winID] EQ 0 THEN Message, 'The image window has been closed.' ; Is the image that you got here the same size as the cgImage image? void = Image_Dimensions(image, XSIZE=imgxsize, YSIZE=imgysize) IF imgxsize NE _cgimage_xsize OR imgysize NE _cgimage_ysize THEN $ Message, 'Image dimensions to not match those of last displayed image.' ; Make the image window the current graphics window. thisWindow = !D.Window WSet, _cgimage_winID ; Are the window sizes still right? IF !D.X_Size NE _cgimage_winxsize OR !D.Y_Size NE _cgimage_winysize THEN BEGIN WSet, thisWindow Message, 'The image window size has changed size from when image was last displayed.' ENDIF ; If a position was supplied, use that rather than the stored position. IF N_Elements(position) NE 0 THEN thePos = position ELSE thePos = _cgimage_position ; Print instructions to the user. Print, '' Print, 'Click cursor in image window (window ' + StrTrim(_cgimage_winID,2) + ') to get image values.' Print, 'Use LEFT mouse buton to inquire.' Print, 'Use RIGHT mouse button to exit program.' Print, '' Print, 'Expecting cursor clicks in image window...' ; Start the image loop. !MOUSE.BUTTON = 0 WHILE !MOUSE.BUTTON NE 4 DO BEGIN ; Change to arrow cursor in window. IF !D.Name EQ 'WIN' THEN BEGIN Device, CURSOR_STANDARD=32649 ENDIF ELSE BEGIN Device, /CURSOR_ORIGINAL ENDELSE ; Get the location in the window. Cursor, x, y, /NORMAL, /DOWN ; Are you inside or outside the image? inside = 0 IF (x GE thePos[0]) AND (x LE thePos[2]) AND $ (y GE thePos[1]) AND (y LE thePos[3]) THEN inside = 1 ; If inside, then convert location to image pixel dimension and return value ; of the image at the location. Be sure you do this differently for 2D and 3D images. IF inside THEN BEGIN ; Create vectors for locating image dimensions with VALUE_LOCATE xvec = cgScaleVector(Findgen(_cgimage_xsize+1), thePos[0], thePos[2]) yvec = cgScaleVector(Findgen(_cgimage_ysize+1), thePos[1], thePos[3]) xpixel = Value_Locate(xvec, x) ypixel = Value_Locate(yvec, y) ;; If a hash wasn't input, use the old output convention. cgImageInfoDescribeValues, image, xpixel, ypixel, hsh ENDIF ELSE Print, 'Outside image' ENDWHILE ; Set the cursor back to original shape. IF !D.Name EQ 'WIN' THEN BEGIN Device, /CURSOR_ORIGINAL ENDIF ELSE BEGIN Device, CURSOR_STANDARD=30 ENDELSE ; Set the window back to entry window. WSet, thisWindow ; Print confirmation. Print, '' Print, 'Good-bye. cgImageInfo has returned control to IDL.' Print, '' END