[133] | 1 | ;+ |
---|
[114] | 2 | ; |
---|
[136] | 3 | ; @file_comments |
---|
[133] | 4 | ; The purpose of this program is to provide an interactive tool that can be used |
---|
| 5 | ; to view JPEG, BMP, GIF, PNG, and TIFF picture files. Images are loaded into |
---|
| 6 | ; memory, so the initial file access may take a while, but once each picture has |
---|
| 7 | ; been opened they can all be viewed in a very rapid fashion. |
---|
| 8 | ; |
---|
[232] | 9 | ; @categories |
---|
[157] | 10 | ; Visualization, Widget |
---|
[133] | 11 | ; |
---|
[157] | 12 | ; @param EVENT {in}{required} |
---|
[133] | 13 | ; |
---|
[136] | 14 | ; @restrictions |
---|
| 15 | ; While this program is running in an IDL session it will change the current |
---|
| 16 | ; working directory, enables/disables color decomposition, and sets !QUIET=1, |
---|
| 17 | ; !ORDER=0, & !P.BACKGROUND=0. These settings are returned to their initial |
---|
| 18 | ; settings before the program was initiated once it is terminated. |
---|
[133] | 19 | ; |
---|
[136] | 20 | ; @restrictions |
---|
| 21 | ; This program is supported in IDL version 5.5 and newer. In order to open |
---|
| 22 | ; GIF files or TIFF files with LZW compression the copy of IDL being used must |
---|
| 23 | ; be licensed with these features. IDL only supports BMP files in the standard |
---|
| 24 | ; Windows format and does not support OS2 bitmaps. |
---|
[133] | 25 | ; |
---|
[232] | 26 | ; @history |
---|
[157] | 27 | ; Written by: AEB, 1/02. |
---|
[133] | 28 | ; |
---|
[157] | 29 | ; @version |
---|
| 30 | ; $Id$ |
---|
[133] | 31 | ;_ |
---|
[231] | 32 | ; |
---|
[163] | 33 | PRO image_viewer_open_files,event |
---|
[133] | 34 | ;THIS PROCEDURE IS CALLED WHEN A USER SELECTS "File > Open Picture Files" FROM THE MAIN MENU |
---|
| 35 | ; |
---|
[114] | 36 | compile_opt idl2, strictarrsubs |
---|
| 37 | ; |
---|
[232] | 38 | ;error handling: |
---|
[133] | 39 | !ERROR_STATE.CODE=0 |
---|
| 40 | CATCH,error |
---|
| 41 | if error NE 0 then begin |
---|
| 42 | HELP,/LAST_MESSAGE,OUTPUT=traceback |
---|
| 43 | messageStr=['Error Caught :','',traceback] |
---|
| 44 | dummy=DIALOG_MESSAGE(messageStr,/ERROR) |
---|
| 45 | ;if status report dialog is still active, destroy it: |
---|
| 46 | if SIZE(tlb,/TYPE) NE 0 then WIDGET_CONTROL,tlb,/DESTROY |
---|
| 47 | RETURN |
---|
| 48 | endif |
---|
| 49 | ;obtain state structure for top-level-base from its UVALUE: |
---|
| 50 | WIDGET_CONTROL,event.top,GET_UVALUE=pState |
---|
| 51 | ;prompt user to select files with native file selection dialog: |
---|
| 52 | if (*pState).gifFlag EQ 1 then filter=['*.JPG','*.jpg','*.JPEG','*.jpeg','*.JPE','*.jpe',$ |
---|
| 53 | '*.JFIF','*.jfif','*.GIF','*.gif','*.BMP','*.bmp','*.TIF','*.tif','*.TIFF','*.tiff',$ |
---|
| 54 | '*.PNG','*.png'] else $ |
---|
| 55 | filter=['*.JPG','*.jpg','*.JPEG','*.jpeg','*.JPE','*.jpe','*.JFIF','*.jfif','*.BMP','*.bmp',$ |
---|
| 56 | '*.TIF','*.tif','*.TIFF','*.tiff','*.PNG','*.png'] |
---|
| 57 | files=DIALOG_PICKFILE(TITLE='Select picture files to open',/MULTIPLE_FILES,$ |
---|
| 58 | FILTER=filter,GET_PATH=path) |
---|
| 59 | ;if user hit "Cancel" then return to previous program level: |
---|
| 60 | if (files[0] EQ '') then RETURN |
---|
| 61 | ;change current working directory to location of selected files: |
---|
| 62 | CD,path |
---|
| 63 | nFiles=N_ELEMENTS(files) |
---|
| 64 | (*pState).nFiles=nFiles |
---|
| 65 | (*pState).increment=100./nFiles |
---|
| 66 | files=files[SORT(files)] |
---|
| 67 | ;create status report dialog: |
---|
| 68 | xCenter=(*pState).screenSize[0]/2 |
---|
| 69 | yCenter=(*pState).screenSize[1]/2 |
---|
| 70 | tlb2=WIDGET_BASE(TITLE='Status Report',/COLUMN,/ALIGN_CENTER,TLB_FRAME_ATTR=19,/MODAL,$ |
---|
| 71 | GROUP_LEADER=(*pState).tlb) |
---|
| 72 | spacer=WIDGET_LABEL(tlb2,VALUE=' ') |
---|
| 73 | label1=WIDGET_LABEL(tlb2,VALUE='LOADING SELECTED IMAGE FILES INTO MEMORY') |
---|
| 74 | spacer=WIDGET_LABEL(tlb2,VALUE=' ') |
---|
| 75 | label2=WIDGET_LABEL(tlb2,VALUE='*** PLEASE WAIT ***') |
---|
| 76 | spacer=WIDGET_LABEL(tlb2,VALUE=' ') |
---|
| 77 | statusBase=WIDGET_BASE(tlb2,/ROW,/FRAME,/BASE_ALIGN_CENTER,/ALIGN_CENTER,EVENT_PRO='image_viewer_timer') |
---|
| 78 | cancelBut=WIDGET_BUTTON(statusBase,VALUE='Cancel',EVENT_PRO='image_viewer_cancel') |
---|
| 79 | progressLabel=WIDGET_LABEL(statusBase,Value=' Progress : 0 ') |
---|
| 80 | statusSlider=WIDGET_SLIDER(statusBase,SENSITIVE=0,TITLE=' ',XSIZE=200) |
---|
| 81 | percentLabel=WIDGET_LABEL(statusBase,VALUE=' 100 %') |
---|
| 82 | geom=WIDGET_INFO(tlb2,/GEOMETRY) |
---|
| 83 | xHalfSize=geom.Scr_XSize/2 |
---|
| 84 | yHalfSize=geom.Scr_YSize/2 |
---|
| 85 | WIDGET_CONTROL,tlb2,XOFFSET=xCenter-xHalfSize,YOFFSET=yCenter-yHalfSize |
---|
| 86 | WIDGET_CONTROL,tlb2,/REALIZE |
---|
| 87 | (*pState).statusBase=statusBase |
---|
| 88 | (*pState).statusSlider=statusSlider |
---|
| 89 | WIDGET_CONTROL,tlb2,SET_UVALUE=pState |
---|
| 90 | ;reset settings of GUI: |
---|
| 91 | WIDGET_CONTROL,(*pState).fileText,SET_VALUE='' |
---|
| 92 | WIDGET_CONTROL,(*pState).imageDraw,GET_VALUE=drawID |
---|
| 93 | WSET,drawID |
---|
| 94 | TVLCT,0,0,0,0 |
---|
| 95 | ERASE |
---|
| 96 | ;re-create thumbnails base with appropriate size for number of images selected: |
---|
| 97 | nRows = CEIL (nFiles / 3.0) |
---|
| 98 | WIDGET_CONTROL,(*pState).thumbBase,/DESTROY |
---|
| 99 | (*pState).thumbBase=WIDGET_BASE((*pState).controlsBase,/COLUMN,/ALIGN_TOP,/FRAME,XSIZE=260,$ |
---|
| 100 | YSIZE=(nRows*89),/SCROLL,X_SCROLL_SIZE=260,Y_SCROLL_SIZE=650) |
---|
| 101 | ;initialize pointer array to reference image data: |
---|
| 102 | numImages=N_ELEMENTS(*(*pState).images) |
---|
| 103 | if numImages NE 0 then PTR_FREE,*(*pState).images |
---|
| 104 | *(*pState).images=PTRARR(nFiles,/ALLOCATE_HEAP) |
---|
| 105 | *(*pState).files=files |
---|
| 106 | ;loop through each file: |
---|
| 107 | (*pState).timer=1B |
---|
| 108 | WIDGET_CONTROL,statusBase,TIMER=0.01 |
---|
| 109 | END |
---|
[232] | 110 | ; |
---|
[133] | 111 | ;+ |
---|
[232] | 112 | ; |
---|
[133] | 113 | ; @param event {in}{required} |
---|
[232] | 114 | ; |
---|
[133] | 115 | ;- |
---|
[163] | 116 | PRO image_viewer_open_folder,event |
---|
[133] | 117 | ;THIS PROCEDURE IS CALLED WHEN A USER SELECTS "File > Open All In Folder" FROM THE MAIN MENU |
---|
[114] | 118 | ; |
---|
| 119 | compile_opt idl2, strictarrsubs |
---|
| 120 | ; |
---|
[232] | 121 | ; error handling: |
---|
[133] | 122 | !ERROR_STATE.CODE=0 |
---|
| 123 | CATCH,error |
---|
| 124 | if error NE 0 then begin |
---|
| 125 | HELP,/LAST_MESSAGE,OUTPUT=traceback |
---|
| 126 | messageStr=['Error Caught :','',traceback] |
---|
| 127 | dummy=DIALOG_MESSAGE(messageStr,/ERROR) |
---|
| 128 | ;if status report dialog is still active, destroy it: |
---|
| 129 | if SIZE(tlb,/TYPE) NE 0 then WIDGET_CONTROL,tlb,/DESTROY |
---|
| 130 | RETURN |
---|
| 131 | endif |
---|
| 132 | ;obtain state structure for top-level-base from its UVALUE: |
---|
| 133 | WIDGET_CONTROL,event.top,GET_UVALUE=pState |
---|
| 134 | ;prompt user to select files with native file selection dialog: |
---|
| 135 | folder=DIALOG_PICKFILE(TITLE='Select folder that contains picture files',/DIRECTORY) |
---|
| 136 | ;if user hit "Cancel" then return to previous program level: |
---|
| 137 | if folder EQ '' then RETURN |
---|
| 138 | ;change current working directory to location of selected files: |
---|
| 139 | CD,folder |
---|
| 140 | if (*pState).gifFlag EQ 1 then filter=['*.JPG','*.JPEG','*.JPE','*.JFIF','*.GIF','*.BMP',$ |
---|
| 141 | '*.TIF','*.TIFF','*.PNG'] else $ |
---|
| 142 | filter=['*.JPG','*.JPEG','*.JPE','*.JFIF','*.BMP','*.TIF','*.TIFF','*.PNG'] |
---|
| 143 | files=FILE_SEARCH(filter,COUNT=nFiles,/FOLD_CASE,/FULLY_QUALIFY_PATH,/NOSORT) |
---|
| 144 | if nFiles EQ 0 then begin |
---|
| 145 | dummy=DIALOG_MESSAGE('No valid picture files were found in the selected folder !',/INFO) |
---|
| 146 | RETURN |
---|
| 147 | endif |
---|
| 148 | (*pState).nFiles=nFiles |
---|
| 149 | (*pState).increment=100./nFiles |
---|
| 150 | files=files[SORT(files)] |
---|
| 151 | ;create status report dialog: |
---|
| 152 | xCenter=(*pState).screenSize[0]/2 |
---|
| 153 | yCenter=(*pState).screenSize[1]/2 |
---|
| 154 | tlb2=WIDGET_BASE(TITLE='Status Report',/COLUMN,/ALIGN_CENTER,TLB_FRAME_ATTR=19,/MODAL,$ |
---|
| 155 | GROUP_LEADER=(*pState).tlb) |
---|
| 156 | spacer=WIDGET_LABEL(tlb2,VALUE=' ') |
---|
| 157 | label1=WIDGET_LABEL(tlb2,VALUE='LOADING SELECTED IMAGE FILES INTO MEMORY') |
---|
| 158 | spacer=WIDGET_LABEL(tlb2,VALUE=' ') |
---|
| 159 | label2=WIDGET_LABEL(tlb2,VALUE='*** PLEASE WAIT ***') |
---|
| 160 | spacer=WIDGET_LABEL(tlb2,VALUE=' ') |
---|
| 161 | statusBase=WIDGET_BASE(tlb2,/ROW,/FRAME,/BASE_ALIGN_CENTER,/ALIGN_CENTER,EVENT_PRO='image_viewer_timer') |
---|
| 162 | cancelBut=WIDGET_BUTTON(statusBase,VALUE='Cancel',EVENT_PRO='image_viewer_cancel') |
---|
| 163 | progressLabel=WIDGET_LABEL(statusBase,Value=' Progress : 0 ') |
---|
| 164 | statusSlider=WIDGET_SLIDER(statusBase,SENSITIVE=0,TITLE=' ',XSIZE=200) |
---|
| 165 | percentLabel=WIDGET_LABEL(statusBase,VALUE=' 100 %') |
---|
| 166 | geom=WIDGET_INFO(tlb2,/GEOMETRY) |
---|
| 167 | xHalfSize=geom.Scr_XSize/2 |
---|
| 168 | yHalfSize=geom.Scr_YSize/2 |
---|
| 169 | WIDGET_CONTROL,tlb2,XOFFSET=xCenter-xHalfSize,YOFFSET=yCenter-yHalfSize |
---|
| 170 | WIDGET_CONTROL,tlb2,/REALIZE |
---|
| 171 | (*pState).statusBase=statusBase |
---|
| 172 | (*pState).statusSlider=statusSlider |
---|
| 173 | WIDGET_CONTROL,tlb2,SET_UVALUE=pState |
---|
| 174 | ;reset settings of GUI: |
---|
| 175 | WIDGET_CONTROL,(*pState).fileText,SET_VALUE='' |
---|
| 176 | WIDGET_CONTROL,(*pState).imageDraw,GET_VALUE=drawID |
---|
| 177 | WSET,drawID |
---|
| 178 | TVLCT,0,0,0,0 |
---|
| 179 | ERASE |
---|
| 180 | ;re-create thumbnails base with appropriate size for number of images selected: |
---|
| 181 | nRows = CEIL (nFiles / 3.0) |
---|
| 182 | WIDGET_CONTROL,(*pState).thumbBase,/DESTROY |
---|
| 183 | (*pState).thumbBase=WIDGET_BASE((*pState).controlsBase,/COLUMN,/ALIGN_TOP,/FRAME,XSIZE=260,$ |
---|
| 184 | YSIZE=(nRows*89),/SCROLL,X_SCROLL_SIZE=260,Y_SCROLL_SIZE=650) |
---|
| 185 | ;initialize pointer array to reference image data: |
---|
| 186 | numImages=N_ELEMENTS(*(*pState).images) |
---|
| 187 | if numImages NE 0 then PTR_FREE,*(*pState).images |
---|
| 188 | *(*pState).images=PTRARR(nFiles,/ALLOCATE_HEAP) |
---|
| 189 | *(*pState).files=files |
---|
| 190 | ;loop through each file: |
---|
| 191 | (*pState).timer=1B |
---|
| 192 | WIDGET_CONTROL,statusBase,TIMER=0.01 |
---|
| 193 | END |
---|
[232] | 194 | ; |
---|
[133] | 195 | ;+ |
---|
[232] | 196 | ; |
---|
[133] | 197 | ; @param event {in}{required} |
---|
[232] | 198 | ; |
---|
[133] | 199 | ;- |
---|
[163] | 200 | PRO image_viewer_cancel,event |
---|
[114] | 201 | ; |
---|
| 202 | compile_opt idl2, strictarrsubs |
---|
| 203 | ; |
---|
[232] | 204 | ;obtain state structure for top-level-base from its UVALUE: |
---|
[133] | 205 | WIDGET_CONTROL,event.top,GET_UVALUE=pState |
---|
| 206 | ;shut-off timer: |
---|
| 207 | (*pState).timer=0B |
---|
| 208 | END |
---|
[232] | 209 | ; |
---|
[133] | 210 | ;+ |
---|
[232] | 211 | ; |
---|
[133] | 212 | ; @param event {in}{required} |
---|
[232] | 213 | ; |
---|
[133] | 214 | ;- |
---|
[163] | 215 | PRO image_viewer_timer,event |
---|
[114] | 216 | ; |
---|
| 217 | compile_opt idl2, strictarrsubs |
---|
| 218 | ; |
---|
[232] | 219 | ;obtain state structure for top-level-base from its UVALUE: |
---|
[133] | 220 | WIDGET_CONTROL,event.top,GET_UVALUE=pState |
---|
| 221 | if (*pState).timer EQ 1 then begin ;continue processing files: |
---|
| 222 | if (*pState).currFile LE (*pState).nFiles-1 then begin |
---|
| 223 | i=(*pState).currFile |
---|
| 224 | extension=STRUPCASE(STRMID((*(*pState).files)[i],STRPOS((*(*pState).files)[i],'.',/REVERSE_SEARCH)+1)) |
---|
| 225 | if extension EQ 'JPG' or extension EQ 'JPEG' or extension EQ 'JPE' or extension EQ 'JFIF' then begin |
---|
| 226 | result=QUERY_JPEG((*(*pState).files)[i],info) |
---|
| 227 | if result NE 1 then begin |
---|
| 228 | dummy=DIALOG_MESSAGE(['Selected file:','',(*(*pState).files)[i],'',$ |
---|
| 229 | 'does not appear to be a valid JPEG file !'],/ERROR) |
---|
| 230 | if (i MOD 3) EQ 0 then (*pState).rowBase=WIDGET_BASE((*pState).thumbBase,/ROW,/ALIGN_LEFT) |
---|
| 231 | if (*pState).currFile EQ (*pState).nFiles-1 then begin |
---|
| 232 | ;last file ... terminate timer: |
---|
| 233 | (*pState).timer=0B |
---|
| 234 | (*pState).currFile=0L |
---|
| 235 | WIDGET_CONTROL,event.top,/DESTROY |
---|
| 236 | endif else begin |
---|
| 237 | ;increment file number and update progress slider: |
---|
| 238 | (*pState).currFile=(*pState).currFile+1 |
---|
| 239 | progressValue = ROUND((i+1)*(*pState).increment) < 100 |
---|
| 240 | WIDGET_CONTROL,(*pState).statusSlider,SET_VALUE=progressValue |
---|
| 241 | ;fire off timer again: |
---|
| 242 | WIDGET_CONTROL,(*pState).statusBase,TIMER=0.01 |
---|
| 243 | endelse |
---|
| 244 | RETURN |
---|
| 245 | endif |
---|
| 246 | if (i MOD 3) EQ 0 then (*pState).rowBase=WIDGET_BASE((*pState).thumbBase,/ROW,/ALIGN_LEFT) |
---|
| 247 | TVLCT,0,0,0,0 |
---|
| 248 | thumbDraw=WIDGET_DRAW((*pState).rowBase,/BUTTON_EVENTS,RETAIN=2,XSIZE=80,YSIZE=80,$ |
---|
| 249 | EVENT_PRO='image_viewer_thumbs',UVALUE=(i+1),UNAME=STRTRIM(i+1,2)) |
---|
| 250 | WAIT,0.01 |
---|
| 251 | WIDGET_CONTROL,thumbDraw,GET_VALUE=drawID |
---|
| 252 | WSET,drawID |
---|
| 253 | if info.channels EQ 3 then begin |
---|
| 254 | READ_JPEG,(*(*pState).files)[i],image,TRUE=1 |
---|
| 255 | if (*pState).colorMode EQ 'PSEUDO' then begin |
---|
| 256 | image=COLOR_QUAN(TEMPORARY(image),1,red,green,blue,COLORS=!D.TABLE_SIZE-1) |
---|
| 257 | red=[[0],TEMPORARY(red)] |
---|
| 258 | green=[[0],TEMPORARY(green)] |
---|
| 259 | blue=[[0],TEMPORARY(blue)] |
---|
| 260 | image=TEMPORARY(image)+1B |
---|
| 261 | imageColorMode='PSEUDO' |
---|
| 262 | TVLCT,red,green,blue |
---|
| 263 | endif else begin |
---|
| 264 | imageColorMode='TRUE' |
---|
| 265 | red=0B |
---|
| 266 | green=0B |
---|
| 267 | blue=0B |
---|
| 268 | DEVICE,DECOMPOSED=1 |
---|
| 269 | endelse |
---|
| 270 | endif |
---|
| 271 | if info.channels EQ 1 then begin |
---|
| 272 | READ_JPEG,(*(*pState).files)[i],image |
---|
| 273 | if (*pState).colorMode EQ 'PSEUDO' then image=BYTSCL(TEMPORARY(image),TOP=!D.TABLE_SIZE-1) |
---|
| 274 | red=BINDGEN(!D.TABLE_SIZE) |
---|
| 275 | green=BINDGEN(!D.TABLE_SIZE) |
---|
| 276 | blue=BINDGEN(!D.TABLE_SIZE) |
---|
| 277 | imageColorMode='PSEUDO' |
---|
| 278 | if (*pState).colorMode EQ 'TRUE' then DEVICE,DECOMPOSED=0 |
---|
| 279 | TVLCT,red,green,blue |
---|
| 280 | endif |
---|
| 281 | ratio=FLOAT(info.dimensions[0])/info.dimensions[1] |
---|
| 282 | ;resize image if necessary: |
---|
| 283 | if info.dimensions[0] GT 710 or info.dimensions[1] GT 650 then begin |
---|
| 284 | if ratio GE 1.09231 then begin |
---|
| 285 | factor=(710./info.dimensions[0]) |
---|
| 286 | xSize=710 |
---|
| 287 | ySize=ROUND(info.dimensions[1]*factor) |
---|
| 288 | if imageColorMode EQ 'PSEUDO' then image=CONGRID(image,710,ySize) |
---|
| 289 | if imageColorMode EQ 'TRUE' then image=CONGRID(image,3,710,ySize) |
---|
| 290 | endif else begin |
---|
| 291 | factor=(650./info.dimensions[1]) |
---|
| 292 | xSize=ROUND(info.dimensions[0]*factor) |
---|
| 293 | ySize=650 |
---|
| 294 | if imageColorMode EQ 'PSEUDO' then image=CONGRID(image,xSize,650) |
---|
| 295 | if imageColorMode EQ 'TRUE' then image=CONGRID(image,3,xSize,650) |
---|
| 296 | endelse |
---|
| 297 | endif else begin |
---|
| 298 | xSize=info.dimensions[0] |
---|
| 299 | ySize=info.dimensions[1] |
---|
| 300 | endelse |
---|
| 301 | ;create thumbnail: |
---|
| 302 | if xSize GT 80 or ySize GT 80 then begin |
---|
| 303 | if ratio GE 1.09231 then begin |
---|
| 304 | factor=(80./info.dimensions[0]) |
---|
| 305 | thumbxSize=80 |
---|
| 306 | thumbySize=ROUND(info.dimensions[1]*factor) |
---|
| 307 | if imageColorMode EQ 'PSEUDO' then thumb=CONGRID(image,80,thumbySize) |
---|
| 308 | if imageColorMode EQ 'TRUE' then thumb=CONGRID(image,3,80,thumbySize) |
---|
| 309 | endif else begin |
---|
| 310 | factor=(80./info.dimensions[1]) |
---|
| 311 | thumbxSize=ROUND(info.dimensions[0]*factor) |
---|
| 312 | thumbySize=80 |
---|
| 313 | if imageColorMode EQ 'PSEUDO' then thumb=CONGRID(image,thumbxSize,80) |
---|
| 314 | if imageColorMode EQ 'TRUE' then thumb=CONGRID(image,3,thumbxSize,80) |
---|
| 315 | endelse |
---|
| 316 | xOffset=ROUND((80-thumbxSize)/2.) |
---|
| 317 | yOffset=ROUND((80-thumbySize)/2.) |
---|
| 318 | endif else begin |
---|
| 319 | bottom=FLOOR((80-ySize)/2.) |
---|
| 320 | top=bottom+ySize-1 |
---|
| 321 | left=FLOOR((80-xSize)/2.) |
---|
| 322 | right=left+xSize-1 |
---|
| 323 | if imageColorMode EQ 'PSEUDO' then begin |
---|
| 324 | thumb=BYTARR(80,80) |
---|
| 325 | thumb[left:right,bottom:top]=image |
---|
| 326 | endif else begin ;imageColorMode EQ 'TRUE': |
---|
| 327 | thumb=BYTARR(3,80,80) |
---|
| 328 | thumb[*,left:right,bottom:top]=image |
---|
| 329 | endelse |
---|
| 330 | xOffset=0 |
---|
| 331 | yOffset=0 |
---|
| 332 | endelse |
---|
| 333 | if imageColorMode EQ 'PSEUDO' then TV,TEMPORARY(thumb),xOffset,yOffset |
---|
| 334 | if imageColorMode EQ 'TRUE' then TV,TEMPORARY(thumb),xOffset,yOffset,TRUE=1 |
---|
| 335 | imageStruct={image:TEMPORARY(image),xSize:xSize,ySize:ySize,imageColorMode:imageColorMode,$ |
---|
| 336 | red:TEMPORARY(red),green:TEMPORARY(green),blue:TEMPORARY(blue)} |
---|
| 337 | *(*(*pState).images)[i]=TEMPORARY(imageStruct) |
---|
| 338 | endif |
---|
| 339 | ; |
---|
| 340 | if extension EQ 'GIF' and (*pState).gifFlag EQ 1 then begin |
---|
| 341 | result=QUERY_GIF((*(*pState).files)[i],info) |
---|
| 342 | if result NE 1 then begin |
---|
| 343 | dummy=DIALOG_MESSAGE(['An error has occurred. This is due to one of the following reasons :','',$ |
---|
| 344 | '1) This installation of IDL is not licensed for GIF technology patented',$ |
---|
| 345 | 'by the Unisys Corporation.','',$ |
---|
| 346 | '2) Selected file:','',(*(*pState).files)[i],'',$ |
---|
| 347 | 'is not a valid GIF file.'],/ERROR) |
---|
| 348 | if (i MOD 3) EQ 0 then (*pState).rowBase=WIDGET_BASE((*pState).thumbBase,/ROW,/ALIGN_LEFT) |
---|
| 349 | if (*pState).currFile EQ (*pState).nFiles-1 then begin |
---|
| 350 | ;last file ... terminate timer: |
---|
| 351 | (*pState).timer=0B |
---|
| 352 | (*pState).currFile=0L |
---|
| 353 | WIDGET_CONTROL,event.top,/DESTROY |
---|
| 354 | endif else begin |
---|
| 355 | ;increment file number and update progress slider: |
---|
| 356 | (*pState).currFile=(*pState).currFile+1 |
---|
| 357 | progressValue = ROUND((i+1)*(*pState).increment) < 100 |
---|
| 358 | WIDGET_CONTROL,(*pState).statusSlider,SET_VALUE=progressValue |
---|
| 359 | ;fire off timer again: |
---|
| 360 | WIDGET_CONTROL,(*pState).statusBase,TIMER=0.01 |
---|
| 361 | endelse |
---|
| 362 | RETURN |
---|
| 363 | endif |
---|
| 364 | if (i MOD 3) EQ 0 then (*pState).rowBase=WIDGET_BASE((*pState).thumbBase,/ROW,/ALIGN_LEFT) |
---|
| 365 | TVLCT,0,0,0,0 |
---|
| 366 | thumbDraw=WIDGET_DRAW((*pState).rowBase,/BUTTON_EVENTS,RETAIN=2,XSIZE=80,YSIZE=80,$ |
---|
| 367 | EVENT_PRO='image_viewer_thumbs',UVALUE=(i+1),UNAME=STRTRIM(i+1,2)) |
---|
| 368 | WAIT,0.01 |
---|
| 369 | WIDGET_CONTROL,thumbDraw,GET_VALUE=drawID |
---|
| 370 | WSET,drawID |
---|
| 371 | if info.has_palette EQ 1 then begin |
---|
| 372 | READ_GIF,(*(*pState).files)[i],image,red,green,blue |
---|
| 373 | trueColorImage=BYTARR(3,info.dimensions[0],info.dimensions[1]) |
---|
| 374 | trueColorImage[0,*,*]=red[image] |
---|
| 375 | trueColorImage[1,*,*]=green[image] |
---|
| 376 | trueColorImage[2,*,*]=blue[image] |
---|
| 377 | image=COLOR_QUAN(TEMPORARY(trueColorImage),1,red,green,blue,COLORS=!D.TABLE_SIZE-1) |
---|
| 378 | red=[[0],TEMPORARY(red)] |
---|
| 379 | green=[[0],TEMPORARY(green)] |
---|
| 380 | blue=[[0],TEMPORARY(blue)] |
---|
| 381 | image=TEMPORARY(image)+1B |
---|
| 382 | endif |
---|
| 383 | if info.has_palette EQ 0 then begin |
---|
| 384 | READ_GIF,(*(*pState).files)[i],image |
---|
| 385 | if (*pState).colorMode EQ 'PSEUDO' then image=BYTSCL(TEMPORARY(image),TOP=!D.TABLE_SIZE-1) |
---|
| 386 | red=BINDGEN(!D.TABLE_SIZE) |
---|
| 387 | green=BINDGEN(!D.TABLE_SIZE) |
---|
| 388 | blue=BINDGEN(!D.TABLE_SIZE) |
---|
| 389 | endif |
---|
| 390 | if (*pState).colorMode EQ 'TRUE' then DEVICE,DECOMPOSED=0 |
---|
| 391 | TVLCT,red,green,blue |
---|
| 392 | imageColorMode='PSEUDO' |
---|
| 393 | ratio=FLOAT(info.dimensions[0])/info.dimensions[1] |
---|
| 394 | ;resize image if necessary: |
---|
| 395 | if info.dimensions[0] GT 710 or info.dimensions[1] GT 650 then begin |
---|
| 396 | if ratio GE 1.09231 then begin |
---|
| 397 | factor=(710./info.dimensions[0]) |
---|
| 398 | xSize=710 |
---|
| 399 | ySize=ROUND(info.dimensions[1]*factor) |
---|
| 400 | image=CONGRID(image,710,ySize) |
---|
| 401 | endif else begin |
---|
| 402 | factor=(650./info.dimensions[1]) |
---|
| 403 | xSize=ROUND(info.dimensions[0]*factor) |
---|
| 404 | ySize=650 |
---|
| 405 | image=CONGRID(image,xSize,650) |
---|
| 406 | endelse |
---|
| 407 | endif else begin |
---|
| 408 | xSize=info.dimensions[0] |
---|
| 409 | ySize=info.dimensions[1] |
---|
| 410 | endelse |
---|
| 411 | ;create thumbnail: |
---|
| 412 | if xSize GT 80 or ySize GT 80 then begin |
---|
| 413 | if ratio GE 1.09231 then begin |
---|
| 414 | factor=(80./info.dimensions[0]) |
---|
| 415 | thumbxSize=80 |
---|
| 416 | thumbySize=ROUND(info.dimensions[1]*factor) |
---|
| 417 | thumb=CONGRID(image,80,thumbySize) |
---|
| 418 | endif else begin |
---|
| 419 | factor=(80./info.dimensions[1]) |
---|
| 420 | thumbxSize=ROUND(info.dimensions[0]*factor) |
---|
| 421 | thumbySize=80 |
---|
| 422 | thumb=CONGRID(image,thumbxSize,80) |
---|
| 423 | endelse |
---|
| 424 | xOffset=ROUND((80-thumbxSize)/2.) |
---|
| 425 | yOffset=ROUND((80-thumbySize)/2.) |
---|
| 426 | endif else begin |
---|
| 427 | bottom=FLOOR((80-ySize)/2.) |
---|
| 428 | top=bottom+ySize-1 |
---|
| 429 | left=FLOOR((80-xSize)/2.) |
---|
| 430 | right=left+xSize-1 |
---|
| 431 | thumb=BYTARR(80,80) |
---|
| 432 | thumb[left:right,bottom:top]=image |
---|
| 433 | xOffset=0 |
---|
| 434 | yOffset=0 |
---|
| 435 | endelse |
---|
| 436 | TV,TEMPORARY(thumb),xOffset,yOffset |
---|
| 437 | imageStruct={image:TEMPORARY(image),xSize:xSize,ySize:ySize,imageColorMode:imageColorMode,$ |
---|
| 438 | red:TEMPORARY(red),green:TEMPORARY(green),blue:TEMPORARY(blue)} |
---|
| 439 | *(*(*pState).images)[i]=TEMPORARY(imageStruct) |
---|
| 440 | endif |
---|
| 441 | ; |
---|
| 442 | if extension EQ 'BMP' then begin |
---|
| 443 | result=QUERY_BMP((*(*pState).files)[i],info) |
---|
| 444 | if result NE 1 then begin |
---|
| 445 | dummy=DIALOG_MESSAGE(['An error has occurred. This is due to one of the following reasons :','',$ |
---|
| 446 | '1) The selected BMP file is an "OS2" format file, which is not supported',$ |
---|
| 447 | 'by IMAGE_VIEWER.','',$ |
---|
| 448 | '2) Selected file:','',(*(*pState).files)[i],'',$ |
---|
| 449 | 'is not a valid BMP file.'],/ERROR) |
---|
| 450 | if (i MOD 3) EQ 0 then (*pState).rowBase=WIDGET_BASE((*pState).thumbBase,/ROW,/ALIGN_LEFT) |
---|
| 451 | if (*pState).currFile EQ (*pState).nFiles-1 then begin |
---|
| 452 | ;last file ... terminate timer: |
---|
| 453 | (*pState).timer=0B |
---|
| 454 | (*pState).currFile=0L |
---|
| 455 | WIDGET_CONTROL,event.top,/DESTROY |
---|
| 456 | endif else begin |
---|
| 457 | ;increment file number and update progress slider: |
---|
| 458 | (*pState).currFile=(*pState).currFile+1 |
---|
| 459 | progressValue = ROUND((i+1)*(*pState).increment) < 100 |
---|
| 460 | WIDGET_CONTROL,(*pState).statusSlider,SET_VALUE=progressValue |
---|
| 461 | ;fire off timer again: |
---|
| 462 | WIDGET_CONTROL,(*pState).statusBase,TIMER=0.01 |
---|
| 463 | endelse |
---|
| 464 | RETURN |
---|
| 465 | endif |
---|
| 466 | if (i MOD 3) EQ 0 then (*pState).rowBase=WIDGET_BASE((*pState).thumbBase,/ROW,/ALIGN_LEFT) |
---|
| 467 | TVLCT,0,0,0,0 |
---|
| 468 | thumbDraw=WIDGET_DRAW((*pState).rowBase,/BUTTON_EVENTS,RETAIN=2,XSIZE=80,YSIZE=80,$ |
---|
| 469 | EVENT_PRO='image_viewer_thumbs',UVALUE=(i+1),UNAME=STRTRIM(i+1,2)) |
---|
| 470 | WAIT,0.01 |
---|
| 471 | WIDGET_CONTROL,thumbDraw,GET_VALUE=drawID |
---|
| 472 | WSET,drawID |
---|
| 473 | if info.channels EQ 3 then begin |
---|
| 474 | image=READ_BMP((*(*pState).files)[i],/RGB) |
---|
| 475 | if (*pState).colorMode EQ 'PSEUDO' then begin |
---|
| 476 | image=COLOR_QUAN(image,1,red,green,blue,COLORS=!D.TABLE_SIZE-1) |
---|
| 477 | red=[[0],TEMPORARY(red)] |
---|
| 478 | green=[[0],TEMPORARY(green)] |
---|
| 479 | blue=[[0],TEMPORARY(blue)] |
---|
| 480 | image=TEMPORARY(image)+1B |
---|
| 481 | imageColorMode='PSEUDO' |
---|
| 482 | TVLCT,red,green,blue |
---|
| 483 | endif else begin |
---|
| 484 | imageColorMode='TRUE' |
---|
| 485 | red=0B |
---|
| 486 | green=0B |
---|
| 487 | blue=0B |
---|
| 488 | DEVICE,DECOMPOSED=1 |
---|
| 489 | endelse |
---|
| 490 | endif |
---|
| 491 | if info.channels EQ 1 then begin |
---|
| 492 | image=READ_BMP((*(*pState).files)[i],red,green,blue) |
---|
| 493 | if info.has_palette EQ 0 then begin |
---|
| 494 | if (*pState).colorMode EQ 'PSEUDO' then image=BYTSCL(TEMPORARY(image),TOP=!D.TABLE_SIZE-1) |
---|
| 495 | red=BINDGEN(!D.TABLE_SIZE) |
---|
| 496 | green=BINDGEN(!D.TABLE_SIZE) |
---|
| 497 | blue=BINDGEN(!D.TABLE_SIZE) |
---|
| 498 | endif else begin |
---|
| 499 | trueColorImage=BYTARR(3,info.dimensions[0],info.dimensions[1]) |
---|
| 500 | trueColorImage[0,*,*]=red[image] |
---|
| 501 | trueColorImage[1,*,*]=green[image] |
---|
| 502 | trueColorImage[2,*,*]=blue[image] |
---|
| 503 | image=COLOR_QUAN(TEMPORARY(trueColorImage),1,red,green,blue,COLORS=!D.TABLE_SIZE-1) |
---|
| 504 | red=[[0],TEMPORARY(red)] |
---|
| 505 | green=[[0],TEMPORARY(green)] |
---|
| 506 | blue=[[0],TEMPORARY(blue)] |
---|
| 507 | image=TEMPORARY(image)+1B |
---|
| 508 | endelse |
---|
| 509 | imageColorMode='PSEUDO' |
---|
| 510 | if (*pState).colorMode EQ 'TRUE' then DEVICE,DECOMPOSED=0 |
---|
| 511 | TVLCT,red,green,blue |
---|
| 512 | endif |
---|
| 513 | ratio=FLOAT(info.dimensions[0])/info.dimensions[1] |
---|
| 514 | ;resize image if necessary: |
---|
| 515 | if info.dimensions[0] GT 710 or info.dimensions[1] GT 650 then begin |
---|
| 516 | if ratio GE 1.09231 then begin |
---|
| 517 | factor=(710./info.dimensions[0]) |
---|
| 518 | xSize=710 |
---|
| 519 | ySize=ROUND(info.dimensions[1]*factor) |
---|
| 520 | if imageColorMode EQ 'PSEUDO' then image=CONGRID(image,710,ySize) |
---|
| 521 | if imageColorMode EQ 'TRUE' then image=CONGRID(image,3,710,ySize) |
---|
| 522 | endif else begin |
---|
| 523 | factor=(650./info.dimensions[1]) |
---|
| 524 | xSize=ROUND(info.dimensions[0]*factor) |
---|
| 525 | ySize=650 |
---|
| 526 | if imageColorMode EQ 'PSEUDO' then image=CONGRID(image,xSize,650) |
---|
| 527 | if imageColorMode EQ 'TRUE' then image=CONGRID(image,3,xSize,650) |
---|
| 528 | endelse |
---|
| 529 | endif else begin |
---|
| 530 | xSize=info.dimensions[0] |
---|
| 531 | ySize=info.dimensions[1] |
---|
| 532 | endelse |
---|
| 533 | ;create thumbnail: |
---|
| 534 | if xSize GT 80 or ySize GT 80 then begin |
---|
| 535 | if ratio GE 1.09231 then begin |
---|
| 536 | factor=(80./info.dimensions[0]) |
---|
| 537 | thumbxSize=80 |
---|
| 538 | thumbySize=ROUND(info.dimensions[1]*factor) |
---|
| 539 | if imageColorMode EQ 'PSEUDO' then thumb=CONGRID(image,80,thumbySize) |
---|
| 540 | if imageColorMode EQ 'TRUE' then thumb=CONGRID(image,3,80,thumbySize) |
---|
| 541 | endif else begin |
---|
| 542 | factor=(80./info.dimensions[1]) |
---|
| 543 | thumbxSize=ROUND(info.dimensions[0]*factor) |
---|
| 544 | thumbySize=80 |
---|
| 545 | if imageColorMode EQ 'PSEUDO' then thumb=CONGRID(image,thumbxSize,80) |
---|
| 546 | if imageColorMode EQ 'TRUE' then thumb=CONGRID(image,3,thumbxSize,80) |
---|
| 547 | endelse |
---|
| 548 | xOffset=ROUND((80-thumbxSize)/2.) |
---|
| 549 | yOffset=ROUND((80-thumbySize)/2.) |
---|
| 550 | endif else begin |
---|
| 551 | bottom=FLOOR((80-ySize)/2.) |
---|
| 552 | top=bottom+ySize-1 |
---|
| 553 | left=FLOOR((80-xSize)/2.) |
---|
| 554 | right=left+xSize-1 |
---|
| 555 | if imageColorMode EQ 'PSEUDO' then begin |
---|
| 556 | thumb=BYTARR(80,80) |
---|
| 557 | thumb[left:right,bottom:top]=image |
---|
| 558 | endif else begin ;imageColorMode EQ 'TRUE': |
---|
| 559 | thumb=BYTARR(3,80,80) |
---|
| 560 | thumb[*,left:right,bottom:top]=image |
---|
| 561 | endelse |
---|
| 562 | xOffset=0 |
---|
| 563 | yOffset=0 |
---|
| 564 | endelse |
---|
| 565 | if imageColorMode EQ 'PSEUDO' then TV,TEMPORARY(thumb),xOffset,yOffset |
---|
| 566 | if imageColorMode EQ 'TRUE' then TV,TEMPORARY(thumb),xOffset,yOffset,TRUE=1 |
---|
| 567 | imageStruct={image:TEMPORARY(image),xSize:xSize,ySize:ySize,imageColorMode:imageColorMode,$ |
---|
| 568 | red:TEMPORARY(red),green:TEMPORARY(green),blue:TEMPORARY(blue)} |
---|
| 569 | *(*(*pState).images)[i]=TEMPORARY(imageStruct) |
---|
| 570 | endif |
---|
| 571 | ; |
---|
| 572 | if extension EQ 'TIF' or extension EQ 'TIFF' then begin |
---|
| 573 | result=QUERY_TIFF((*(*pState).files)[i],info) |
---|
| 574 | if result NE 1 then begin |
---|
| 575 | dummy=DIALOG_MESSAGE(['An error has occurred. This is due to one of the following reasons :','',$ |
---|
| 576 | '1) The selected TIFF file has LZW (Lempel-Zif-Welch) compression and this installation',$ |
---|
| 577 | 'of IDL is not licensed for TIFF LZW technology patented by the Unisys Corporation.','',$ |
---|
| 578 | '2) Selected file:','',(*(*pState).files)[i],'',$ |
---|
| 579 | 'is not a valid TIFF file.'],/ERROR) |
---|
| 580 | if (i MOD 3) EQ 0 then (*pState).rowBase=WIDGET_BASE((*pState).thumbBase,/ROW,/ALIGN_LEFT) |
---|
| 581 | if (*pState).currFile EQ (*pState).nFiles-1 then begin |
---|
| 582 | ;last file ... terminate timer: |
---|
| 583 | (*pState).timer=0B |
---|
| 584 | (*pState).currFile=0L |
---|
| 585 | WIDGET_CONTROL,event.top,/DESTROY |
---|
| 586 | endif else begin |
---|
| 587 | ;increment file number and update progress slider: |
---|
| 588 | (*pState).currFile=(*pState).currFile+1 |
---|
| 589 | progressValue = ROUND((i+1)*(*pState).increment) < 100 |
---|
| 590 | WIDGET_CONTROL,(*pState).statusSlider,SET_VALUE=progressValue |
---|
| 591 | ;fire off timer again: |
---|
| 592 | WIDGET_CONTROL,(*pState).statusBase,TIMER=0.01 |
---|
| 593 | endelse |
---|
| 594 | RETURN |
---|
| 595 | endif |
---|
| 596 | if info.orientation NE 0 and info.orientation NE 1 and info.orientation NE 4 then begin |
---|
| 597 | dummy=DIALOG_MESSAGE('IMAGE_VIEWER only works with standard orientation TIFF files !',/ERROR) |
---|
| 598 | if (i MOD 3) EQ 0 then (*pState).rowBase=WIDGET_BASE((*pState).thumbBase,/ROW,/ALIGN_LEFT) |
---|
| 599 | if (*pState).currFile EQ (*pState).nFiles-1 then begin |
---|
| 600 | ;last file ... terminate timer: |
---|
| 601 | (*pState).timer=0B |
---|
| 602 | (*pState).currFile=0L |
---|
| 603 | WIDGET_CONTROL,event.top,/DESTROY |
---|
| 604 | endif else begin |
---|
| 605 | ;increment file number and update progress slider: |
---|
| 606 | (*pState).currFile=(*pState).currFile+1 |
---|
| 607 | progressValue = ROUND((i+1)*(*pState).increment) < 100 |
---|
| 608 | WIDGET_CONTROL,(*pState).statusSlider,SET_VALUE=progressValue |
---|
| 609 | ;fire off timer again: |
---|
| 610 | WIDGET_CONTROL,(*pState).statusBase,TIMER=0.01 |
---|
| 611 | endelse |
---|
| 612 | RETURN |
---|
| 613 | endif |
---|
| 614 | if (i MOD 3) EQ 0 then (*pState).rowBase=WIDGET_BASE((*pState).thumbBase,/ROW,/ALIGN_LEFT) |
---|
| 615 | TVLCT,0,0,0,0 |
---|
| 616 | thumbDraw=WIDGET_DRAW((*pState).rowBase,/BUTTON_EVENTS,RETAIN=2,XSIZE=80,YSIZE=80,$ |
---|
| 617 | EVENT_PRO='image_viewer_thumbs',UVALUE=(i+1),UNAME=STRTRIM(i+1,2)) |
---|
| 618 | WAIT,0.01 |
---|
| 619 | WIDGET_CONTROL,thumbDraw,GET_VALUE=drawID |
---|
| 620 | WSET,drawID |
---|
| 621 | if info.channels EQ 3 then begin |
---|
| 622 | image=READ_TIFF((*(*pState).files)[i],INTERLEAVE=0,ORDER=order,IMAGE_INDEX=0) |
---|
| 623 | if info.pixel_type NE 1 then image=BYTSCL(TEMPORARY(image)) |
---|
| 624 | if order EQ 1 then begin |
---|
| 625 | ;flip image: |
---|
| 626 | rImage=REFORM(image[0,*,*]) |
---|
| 627 | rImage=ROTATE(rImage,7) |
---|
| 628 | gImage=REFORM(image[1,*,*]) |
---|
| 629 | gImage=ROTATE(gImage,7) |
---|
| 630 | bImage=REFORM(image[2,*,*]) |
---|
| 631 | bImage=ROTATE(bImage,7) |
---|
| 632 | image=BYTARR(3,info.dimensions[0],info.dimensions[1]) |
---|
| 633 | image[0,*,*]=TEMPORARY(rImage) |
---|
| 634 | image[1,*,*]=TEMPORARY(gImage) |
---|
| 635 | image[2,*,*]=TEMPORARY(bImage) |
---|
| 636 | endif |
---|
| 637 | if (*pState).colorMode EQ 'PSEUDO' then begin |
---|
| 638 | image=COLOR_QUAN(image,1,red,green,blue,COLORS=!D.TABLE_SIZE-1) |
---|
| 639 | red=[[0],TEMPORARY(red)] |
---|
| 640 | green=[[0],TEMPORARY(green)] |
---|
| 641 | blue=[[0],TEMPORARY(blue)] |
---|
| 642 | image=TEMPORARY(image)+1B |
---|
| 643 | imageColorMode='PSEUDO' |
---|
| 644 | TVLCT,red,green,blue |
---|
| 645 | endif else begin |
---|
| 646 | imageColorMode='TRUE' |
---|
| 647 | red=0B |
---|
| 648 | green=0B |
---|
| 649 | blue=0B |
---|
| 650 | DEVICE,DECOMPOSED=1 |
---|
| 651 | endelse |
---|
| 652 | endif |
---|
| 653 | if info.channels EQ 1 then begin |
---|
| 654 | image=READ_TIFF((*(*pState).files)[i],red,green,blue,ORDER=order,IMAGE_INDEX=0) |
---|
| 655 | if info.pixel_type NE 1 then image=BYTSCL(TEMPORARY(image)) |
---|
| 656 | if order EQ 1 then begin |
---|
| 657 | ;flip image: |
---|
| 658 | image=ROTATE(TEMPORARY(image),7) |
---|
| 659 | endif |
---|
| 660 | if info.has_palette EQ 0 then begin |
---|
| 661 | if (*pState).colorMode EQ 'PSEUDO' then image=BYTSCL(TEMPORARY(image),TOP=!D.TABLE_SIZE-1) |
---|
| 662 | red=BINDGEN(!D.TABLE_SIZE) |
---|
| 663 | green=BINDGEN(!D.TABLE_SIZE) |
---|
| 664 | blue=BINDGEN(!D.TABLE_SIZE) |
---|
| 665 | endif else begin |
---|
| 666 | trueColorImage=BYTARR(3,info.dimensions[0],info.dimensions[1]) |
---|
| 667 | trueColorImage[0,*,*]=red[image] |
---|
| 668 | trueColorImage[1,*,*]=green[image] |
---|
| 669 | trueColorImage[2,*,*]=blue[image] |
---|
| 670 | image=COLOR_QUAN(TEMPORARY(trueColorImage),1,red,green,blue,COLORS=!D.TABLE_SIZE-1) |
---|
| 671 | red=[[0],TEMPORARY(red)] |
---|
| 672 | green=[[0],TEMPORARY(green)] |
---|
| 673 | blue=[[0],TEMPORARY(blue)] |
---|
| 674 | image=TEMPORARY(image)+1B |
---|
| 675 | endelse |
---|
| 676 | imageColorMode='PSEUDO' |
---|
| 677 | if (*pState).colorMode EQ 'TRUE' then DEVICE,DECOMPOSED=0 |
---|
| 678 | TVLCT,red,green,blue |
---|
| 679 | endif |
---|
| 680 | ratio=FLOAT(info.dimensions[0])/info.dimensions[1] |
---|
| 681 | ;resize image if necessary: |
---|
| 682 | if info.dimensions[0] GT 710 or info.dimensions[1] GT 650 then begin |
---|
| 683 | if ratio GE 1.09231 then begin |
---|
| 684 | factor=(710./info.dimensions[0]) |
---|
| 685 | xSize=710 |
---|
| 686 | ySize=ROUND(info.dimensions[1]*factor) |
---|
| 687 | if imageColorMode EQ 'PSEUDO' then image=CONGRID(image,710,ySize) |
---|
| 688 | if imageColorMode EQ 'TRUE' then image=CONGRID(image,3,710,ySize) |
---|
| 689 | endif else begin |
---|
| 690 | factor=(650./info.dimensions[1]) |
---|
| 691 | xSize=ROUND(info.dimensions[0]*factor) |
---|
| 692 | ySize=650 |
---|
| 693 | if imageColorMode EQ 'PSEUDO' then image=CONGRID(image,xSize,650) |
---|
| 694 | if imageColorMode EQ 'TRUE' then image=CONGRID(image,3,xSize,650) |
---|
| 695 | endelse |
---|
| 696 | endif else begin |
---|
| 697 | xSize=info.dimensions[0] |
---|
| 698 | ySize=info.dimensions[1] |
---|
| 699 | endelse |
---|
| 700 | ;create thumbnail: |
---|
| 701 | if xSize GT 80 or ySize GT 80 then begin |
---|
| 702 | if ratio GE 1.09231 then begin |
---|
| 703 | factor=(80./info.dimensions[0]) |
---|
| 704 | thumbxSize=80 |
---|
| 705 | thumbySize=ROUND(info.dimensions[1]*factor) |
---|
| 706 | if imageColorMode EQ 'PSEUDO' then thumb=CONGRID(image,80,thumbySize) |
---|
| 707 | if imageColorMode EQ 'TRUE' then thumb=CONGRID(image,3,80,thumbySize) |
---|
| 708 | endif else begin |
---|
| 709 | factor=(80./info.dimensions[1]) |
---|
| 710 | thumbxSize=ROUND(info.dimensions[0]*factor) |
---|
| 711 | thumbySize=80 |
---|
| 712 | if imageColorMode EQ 'PSEUDO' then thumb=CONGRID(image,thumbxSize,80) |
---|
| 713 | if imageColorMode EQ 'TRUE' then thumb=CONGRID(image,3,thumbxSize,80) |
---|
| 714 | endelse |
---|
| 715 | xOffset=ROUND((80-thumbxSize)/2.) |
---|
| 716 | yOffset=ROUND((80-thumbySize)/2.) |
---|
| 717 | endif else begin |
---|
| 718 | bottom=FLOOR((80-ySize)/2.) |
---|
| 719 | top=bottom+ySize-1 |
---|
| 720 | left=FLOOR((80-xSize)/2.) |
---|
| 721 | right=left+xSize-1 |
---|
| 722 | if imageColorMode EQ 'PSEUDO' then begin |
---|
| 723 | thumb=BYTARR(80,80) |
---|
| 724 | thumb[left:right,bottom:top]=image |
---|
| 725 | endif else begin ;imageColorMode EQ 'TRUE': |
---|
| 726 | thumb=BYTARR(3,80,80) |
---|
| 727 | thumb[*,left:right,bottom:top]=image |
---|
| 728 | endelse |
---|
| 729 | xOffset=0 |
---|
| 730 | yOffset=0 |
---|
| 731 | endelse |
---|
| 732 | if imageColorMode EQ 'PSEUDO' then TV,TEMPORARY(thumb),xOffset,yOffset |
---|
| 733 | if imageColorMode EQ 'TRUE' then TV,TEMPORARY(thumb),xOffset,yOffset,TRUE=1 |
---|
| 734 | imageStruct={image:TEMPORARY(image),xSize:xSize,ySize:ySize,imageColorMode:imageColorMode,$ |
---|
| 735 | red:TEMPORARY(red),green:TEMPORARY(green),blue:TEMPORARY(blue)} |
---|
| 736 | *(*(*pState).images)[i]=TEMPORARY(imageStruct) |
---|
| 737 | endif |
---|
| 738 | ; |
---|
| 739 | if extension EQ 'PNG' then begin |
---|
| 740 | result=QUERY_PNG((*(*pState).files)[i],info) |
---|
| 741 | if result NE 1 then begin |
---|
| 742 | dummy=DIALOG_MESSAGE(['Selected file:','',(*(*pState).files)[i],'',$ |
---|
| 743 | 'does not appear to be a valid PNG file !'],/ERROR) |
---|
| 744 | if (i MOD 3) EQ 0 then (*pState).rowBase=WIDGET_BASE((*pState).thumbBase,/ROW,/ALIGN_LEFT) |
---|
| 745 | if (*pState).currFile EQ (*pState).nFiles-1 then begin |
---|
| 746 | ;last file ... terminate timer: |
---|
| 747 | (*pState).timer=0B |
---|
| 748 | (*pState).currFile=0L |
---|
| 749 | WIDGET_CONTROL,event.top,/DESTROY |
---|
| 750 | endif else begin |
---|
| 751 | ;increment file number and update progress slider: |
---|
| 752 | (*pState).currFile=(*pState).currFile+1 |
---|
| 753 | progressValue = ROUND((i+1)*(*pState).increment) < 100 |
---|
| 754 | WIDGET_CONTROL,(*pState).statusSlider,SET_VALUE=progressValue |
---|
| 755 | ;fire off timer again: |
---|
| 756 | WIDGET_CONTROL,(*pState).statusBase,TIMER=0.01 |
---|
| 757 | endelse |
---|
| 758 | RETURN |
---|
| 759 | endif |
---|
| 760 | if (i MOD 3) EQ 0 then (*pState).rowBase=WIDGET_BASE((*pState).thumbBase,/ROW,/ALIGN_LEFT) |
---|
| 761 | TVLCT,0,0,0,0 |
---|
| 762 | thumbDraw=WIDGET_DRAW((*pState).rowBase,/BUTTON_EVENTS,RETAIN=2,XSIZE=80,YSIZE=80,$ |
---|
| 763 | EVENT_PRO='image_viewer_thumbs',UVALUE=(i+1),UNAME=STRTRIM(i+1,2)) |
---|
| 764 | WAIT,0.01 |
---|
| 765 | WIDGET_CONTROL,thumbDraw,GET_VALUE=drawID |
---|
| 766 | WSET,drawID |
---|
| 767 | if info.channels EQ 3 then begin |
---|
| 768 | image=READ_PNG((*(*pState).files)[i]) |
---|
| 769 | if info.pixel_type NE 1 then image=BYTSCL(TEMPORARY(image)) |
---|
| 770 | if (*pState).colorMode EQ 'PSEUDO' then begin |
---|
| 771 | image=COLOR_QUAN(image,1,red,green,blue,COLORS=!D.TABLE_SIZE-1) |
---|
| 772 | red=[[0],TEMPORARY(red)] |
---|
| 773 | green=[[0],TEMPORARY(green)] |
---|
| 774 | blue=[[0],TEMPORARY(blue)] |
---|
| 775 | image=TEMPORARY(image)+1B |
---|
| 776 | imageColorMode='PSEUDO' |
---|
| 777 | TVLCT,red,green,blue |
---|
| 778 | endif else begin |
---|
| 779 | imageColorMode='TRUE' |
---|
| 780 | red=0B |
---|
| 781 | green=0B |
---|
| 782 | blue=0B |
---|
| 783 | DEVICE,DECOMPOSED=1 |
---|
| 784 | endelse |
---|
| 785 | endif |
---|
| 786 | if info.channels EQ 1 then begin |
---|
| 787 | image=READ_PNG((*(*pState).files)[i],red,green,blue) |
---|
| 788 | if info.pixel_type NE 1 then image=BYTSCL(TEMPORARY(image)) |
---|
| 789 | if info.has_palette EQ 0 then begin |
---|
| 790 | if (*pState).colorMode EQ 'PSEUDO' then image=BYTSCL(TEMPORARY(image),TOP=!D.TABLE_SIZE-1) |
---|
| 791 | red=BINDGEN(!D.TABLE_SIZE) |
---|
| 792 | green=BINDGEN(!D.TABLE_SIZE) |
---|
| 793 | blue=BINDGEN(!D.TABLE_SIZE) |
---|
| 794 | endif else begin |
---|
| 795 | trueColorImage=BYTARR(3,info.dimensions[0],info.dimensions[1]) |
---|
| 796 | trueColorImage[0,*,*]=red[image] |
---|
| 797 | trueColorImage[1,*,*]=green[image] |
---|
| 798 | trueColorImage[2,*,*]=blue[image] |
---|
| 799 | image=COLOR_QUAN(TEMPORARY(trueColorImage),1,red,green,blue,COLORS=!D.TABLE_SIZE-1) |
---|
| 800 | red=[[0],TEMPORARY(red)] |
---|
| 801 | green=[[0],TEMPORARY(green)] |
---|
| 802 | blue=[[0],TEMPORARY(blue)] |
---|
| 803 | image=TEMPORARY(image)+1B |
---|
| 804 | endelse |
---|
| 805 | imageColorMode='PSEUDO' |
---|
| 806 | if (*pState).colorMode EQ 'TRUE' then DEVICE,DECOMPOSED=0 |
---|
| 807 | TVLCT,red,green,blue |
---|
| 808 | endif |
---|
| 809 | ratio=FLOAT(info.dimensions[0])/info.dimensions[1] |
---|
| 810 | ;resize image if necessary: |
---|
| 811 | if info.dimensions[0] GT 710 or info.dimensions[1] GT 650 then begin |
---|
| 812 | if ratio GE 1.09231 then begin |
---|
| 813 | factor=(710./info.dimensions[0]) |
---|
| 814 | xSize=710 |
---|
| 815 | ySize=ROUND(info.dimensions[1]*factor) |
---|
| 816 | if imageColorMode EQ 'PSEUDO' then image=CONGRID(image,710,ySize) |
---|
| 817 | if imageColorMode EQ 'TRUE' then image=CONGRID(image,3,710,ySize) |
---|
| 818 | endif else begin |
---|
| 819 | factor=(650./info.dimensions[1]) |
---|
| 820 | xSize=ROUND(info.dimensions[0]*factor) |
---|
| 821 | ySize=650 |
---|
| 822 | if imageColorMode EQ 'PSEUDO' then image=CONGRID(image,xSize,650) |
---|
| 823 | if imageColorMode EQ 'TRUE' then image=CONGRID(image,3,xSize,650) |
---|
| 824 | endelse |
---|
| 825 | endif else begin |
---|
| 826 | xSize=info.dimensions[0] |
---|
| 827 | ySize=info.dimensions[1] |
---|
| 828 | endelse |
---|
| 829 | ;create thumbnail: |
---|
| 830 | if xSize GT 80 or ySize GT 80 then begin |
---|
| 831 | if ratio GE 1.09231 then begin |
---|
| 832 | factor=(80./info.dimensions[0]) |
---|
| 833 | thumbxSize=80 |
---|
| 834 | thumbySize=ROUND(info.dimensions[1]*factor) |
---|
| 835 | if imageColorMode EQ 'PSEUDO' then thumb=CONGRID(image,80,thumbySize) |
---|
| 836 | if imageColorMode EQ 'TRUE' then thumb=CONGRID(image,3,80,thumbySize) |
---|
| 837 | endif else begin |
---|
| 838 | factor=(80./info.dimensions[1]) |
---|
| 839 | thumbxSize=ROUND(info.dimensions[0]*factor) |
---|
| 840 | thumbySize=80 |
---|
| 841 | if imageColorMode EQ 'PSEUDO' then thumb=CONGRID(image,thumbxSize,80) |
---|
| 842 | if imageColorMode EQ 'TRUE' then thumb=CONGRID(image,3,thumbxSize,80) |
---|
| 843 | endelse |
---|
| 844 | xOffset=ROUND((80-thumbxSize)/2.) |
---|
| 845 | yOffset=ROUND((80-thumbySize)/2.) |
---|
| 846 | endif else begin |
---|
| 847 | bottom=FLOOR((80-ySize)/2.) |
---|
| 848 | top=bottom+ySize-1 |
---|
| 849 | left=FLOOR((80-xSize)/2.) |
---|
| 850 | right=left+xSize-1 |
---|
| 851 | if imageColorMode EQ 'PSEUDO' then begin |
---|
| 852 | thumb=BYTARR(80,80) |
---|
| 853 | thumb[left:right,bottom:top]=image |
---|
| 854 | endif else begin ;imageColorMode EQ 'TRUE': |
---|
| 855 | thumb=BYTARR(3,80,80) |
---|
| 856 | thumb[*,left:right,bottom:top]=image |
---|
| 857 | endelse |
---|
| 858 | xOffset=0 |
---|
| 859 | yOffset=0 |
---|
| 860 | endelse |
---|
| 861 | if imageColorMode EQ 'PSEUDO' then TV,TEMPORARY(thumb),xOffset,yOffset |
---|
| 862 | if imageColorMode EQ 'TRUE' then TV,TEMPORARY(thumb),xOffset,yOffset,TRUE=1 |
---|
| 863 | imageStruct={image:TEMPORARY(image),xSize:xSize,ySize:ySize,imageColorMode:imageColorMode,$ |
---|
| 864 | red:TEMPORARY(red),green:TEMPORARY(green),blue:TEMPORARY(blue)} |
---|
| 865 | *(*(*pState).images)[i]=TEMPORARY(imageStruct) |
---|
| 866 | endif |
---|
| 867 | ;increment file number and update progress slider: |
---|
| 868 | (*pState).currFile=(*pState).currFile+1 |
---|
| 869 | progressValue = ROUND((i+1)*(*pState).increment) < 100 |
---|
| 870 | WIDGET_CONTROL,(*pState).statusSlider,SET_VALUE=progressValue |
---|
| 871 | ;fire off timer again: |
---|
| 872 | WIDGET_CONTROL,(*pState).statusBase,TIMER=0.01 |
---|
| 873 | endif else begin ;all files have already been read-in: |
---|
| 874 | (*pState).timer=0B |
---|
| 875 | (*pState).currFile=0L |
---|
| 876 | WIDGET_CONTROL,event.top,/DESTROY |
---|
| 877 | endelse |
---|
| 878 | endif else begin ;user hit "Cancel": |
---|
| 879 | (*pState).currFile=0L |
---|
| 880 | WIDGET_CONTROL,event.top,/DESTROY |
---|
| 881 | endelse |
---|
| 882 | END |
---|
[232] | 883 | ; |
---|
[133] | 884 | ;+ |
---|
[232] | 885 | ; |
---|
[133] | 886 | ; @param event {in}{required} |
---|
[232] | 887 | ; |
---|
[133] | 888 | ;- |
---|
[163] | 889 | PRO image_viewer_exit,event |
---|
[114] | 890 | ; |
---|
| 891 | compile_opt idl2, strictarrsubs |
---|
| 892 | ; |
---|
[232] | 893 | ;THIS PROCEDURE IS CALLED WHEN A USER SELECTS "File > Exit" FROM THE MAIN MENU |
---|
| 894 | ;terminate the program by destroying the top-level-base (widgetID always stored in event.top): |
---|
[133] | 895 | WIDGET_CONTROL,event.top,/DESTROY |
---|
| 896 | END |
---|
[232] | 897 | ; |
---|
[133] | 898 | ;+ |
---|
[232] | 899 | ; |
---|
[133] | 900 | ; @param event {in}{required} |
---|
[232] | 901 | ; |
---|
[133] | 902 | ;- |
---|
[163] | 903 | PRO image_viewer_help,event |
---|
[133] | 904 | ;THIS PROCEDURE IS CALLED WHEN A USER SELECTS "Help > Help on IMAGE_VIEWER" |
---|
| 905 | ;FROM THE MAIN MENU |
---|
[114] | 906 | ; |
---|
| 907 | compile_opt idl2, strictarrsubs |
---|
| 908 | ; |
---|
[232] | 909 | ;display a simple message: |
---|
[133] | 910 | messageStr=['IMAGE_VIEWER written by AEB, 2002.','',$ |
---|
| 911 | 'The purpose of this program is to provide an interactive tool that can be used',$ |
---|
| 912 | 'to view JPEG, BMP, GIF, PNG, and TIFF picture files. In order to provide rapid',$ |
---|
| 913 | 'viewing capabilities the images are loaded into memory, which can cause the',$ |
---|
| 914 | 'initial file access to take a bit of time while the pictures are opened and',$ |
---|
| 915 | 'thumbnails are created.'] |
---|
| 916 | dummy=DIALOG_MESSAGE(messageStr,/info) |
---|
| 917 | END |
---|
[232] | 918 | ; |
---|
[133] | 919 | ;+ |
---|
[232] | 920 | ; |
---|
[133] | 921 | ; @param event {in}{required} |
---|
[232] | 922 | ; |
---|
[133] | 923 | ;- |
---|
[163] | 924 | PRO image_viewer_thumbs,event |
---|
[133] | 925 | ;THIS PROCEDURE IS CALLED WHEN A USER CLICKS ON ONE OF THE THUMBNAIL PICTURES |
---|
[114] | 926 | ; |
---|
| 927 | compile_opt idl2, strictarrsubs |
---|
| 928 | ; |
---|
[232] | 929 | ;error handling: |
---|
[133] | 930 | !ERROR_STATE.CODE=0 |
---|
| 931 | CATCH,error |
---|
| 932 | if error NE 0 then begin |
---|
| 933 | HELP,/LAST_MESSAGE,OUTPUT=traceback |
---|
| 934 | messageStr=['Error Caught :','',traceback] |
---|
| 935 | dummy=DIALOG_MESSAGE(messageStr,/ERROR) |
---|
| 936 | RETURN |
---|
| 937 | endif |
---|
| 938 | if event.press EQ 1 then begin |
---|
| 939 | WIDGET_CONTROL,/HOURGLASS |
---|
| 940 | ;obtain state structure for top-level-base from its UVALUE: |
---|
| 941 | WIDGET_CONTROL,event.top,GET_UVALUE=pState |
---|
| 942 | WIDGET_CONTROL,(*pState).imageDraw,GET_VALUE=drawID |
---|
| 943 | WSET,drawID |
---|
| 944 | TVLCT,0,0,0,0 |
---|
| 945 | ERASE |
---|
| 946 | ;obtain current image data: |
---|
| 947 | WIDGET_CONTROL,event.id,GET_UVALUE=fileID |
---|
| 948 | imageStruct=*(*(*pState).images)[fileID-1] |
---|
| 949 | xOffset=ROUND((710-imageStruct.xSize)/2.) |
---|
| 950 | yOffset=ROUND((650-imageStruct.ySize)/2.) |
---|
| 951 | if (*pState).colorMode EQ 'PSEUDO' then begin |
---|
| 952 | TVLCT,imageStruct.red,imageStruct.green,imageStruct.blue |
---|
| 953 | TV,TEMPORARY(imageStruct.image),xOffset,yOffset |
---|
| 954 | endif else begin ;(*pState).colorMode EQ 'TRUE': |
---|
| 955 | if imageStruct.imageColorMode EQ 'PSEUDO' then begin |
---|
| 956 | DEVICE,DECOMPOSED=0 |
---|
| 957 | TVLCT,imageStruct.red,imageStruct.green,imageStruct.blue |
---|
| 958 | TV,TEMPORARY(imageStruct.image),xOffset,yOffset |
---|
| 959 | endif else begin ;imageStruct.imageColorMode EQ 'TRUE': |
---|
| 960 | DEVICE,DECOMPOSED=1 |
---|
| 961 | TV,TEMPORARY(imageStruct.image),xOffset,yOffset,TRUE=1 |
---|
| 962 | endelse |
---|
| 963 | endelse |
---|
| 964 | WIDGET_CONTROL,(*pState).fileText,SET_VALUE=(*(*pState).files)[fileID-1] |
---|
| 965 | endif |
---|
| 966 | END |
---|
[232] | 967 | ; |
---|
[133] | 968 | ;+ |
---|
[232] | 969 | ; |
---|
[136] | 970 | ; @param widgetID {in}{required} |
---|
[232] | 971 | ; |
---|
[133] | 972 | ;- |
---|
[163] | 973 | PRO image_viewer_cleanup,widgetID |
---|
[133] | 974 | ;THIS PROCEDURE IS CALLED WHEN THE PROGRAM IS TERMINATED AND XMANAGER REGISTERS A CLEANUP: |
---|
[114] | 975 | ; |
---|
| 976 | compile_opt idl2, strictarrsubs |
---|
| 977 | ; |
---|
[232] | 978 | ;obtain state structure for top-level-base from its uvalue: |
---|
[133] | 979 | WIDGET_CONTROL,widgetID,GET_UVALUE=pState |
---|
| 980 | ;test for validity of state structure pointer: |
---|
| 981 | if PTR_VALID(pState) then begin |
---|
| 982 | ;reset original settings: |
---|
| 983 | !QUIET=(*pState).quietInit |
---|
| 984 | !ORDER=(*pState).orderInit |
---|
| 985 | !P.BACKGROUND=(*pState).backInit |
---|
| 986 | CD,(*pState).currentDir |
---|
| 987 | DEVICE,DECOMPOSED=(*pState).dc |
---|
| 988 | TVLCT,(*pState).r,(*pState).g,(*pState).b |
---|
| 989 | ;cleanup heap memory: |
---|
| 990 | PTR_FREE,TEMPORARY((*pState).files) |
---|
| 991 | numImages=N_ELEMENTS(*(*pState).images) |
---|
| 992 | if numImages NE 0 then PTR_FREE,*(*pState).images |
---|
| 993 | PTR_FREE,TEMPORARY((*pState).images) |
---|
| 994 | PTR_FREE,TEMPORARY(pState) |
---|
| 995 | endif |
---|
| 996 | END |
---|
[232] | 997 | ; |
---|
[133] | 998 | ;+ |
---|
[232] | 999 | ; |
---|
[133] | 1000 | ; @param event {in}{required} |
---|
[232] | 1001 | ; |
---|
[133] | 1002 | ;- |
---|
[163] | 1003 | PRO image_viewer_event,event |
---|
[133] | 1004 | ;THIS PROCEDURE IS CALLED WHEN A USER RESIZES THE TOP-LEVEL BASE |
---|
[114] | 1005 | ; |
---|
| 1006 | compile_opt idl2, strictarrsubs |
---|
| 1007 | ; |
---|
[232] | 1008 | ;error handling: |
---|
[133] | 1009 | !ERROR_STATE.CODE=0 |
---|
| 1010 | CATCH,error |
---|
| 1011 | if error NE 0 then begin |
---|
| 1012 | HELP,/LAST_MESSAGE,OUTPUT=traceback |
---|
| 1013 | messageStr=['Error Caught :','',traceback] |
---|
| 1014 | dummy=DIALOG_MESSAGE(messageStr,/ERROR) |
---|
| 1015 | RETURN |
---|
| 1016 | endif |
---|
| 1017 | ;obtain state structure for top-level-base from its UVALUE: |
---|
| 1018 | WIDGET_CONTROL,event.top,GET_UVALUE=pState |
---|
| 1019 | ;reset widget size: |
---|
| 1020 | WIDGET_CONTROL,event.top,XSIZE=(*pState).tlbWidth,YSIZE=(*pState).tlbHeight,XOFFSET=0,YOFFSET=0 |
---|
| 1021 | END |
---|
[232] | 1022 | ; |
---|
| 1023 | ;+ |
---|
| 1024 | ; |
---|
| 1025 | ;- |
---|
[163] | 1026 | PRO image_viewer |
---|
[114] | 1027 | ; |
---|
| 1028 | compile_opt idl2, strictarrsubs |
---|
| 1029 | ; |
---|
[232] | 1030 | ;error handling: |
---|
[133] | 1031 | !ERROR_STATE.CODE=0 |
---|
| 1032 | CATCH,error |
---|
| 1033 | if error NE 0 then begin |
---|
| 1034 | HELP,/LAST_MESSAGE,OUTPUT=traceback |
---|
| 1035 | messageStr=['Error Caught :','',traceback] |
---|
| 1036 | dummy=DIALOG_MESSAGE(messageStr,/ERROR) |
---|
| 1037 | !QUIET=quietInit |
---|
| 1038 | !ORDER=orderInit |
---|
| 1039 | !P.BACKGROUND=backInit |
---|
| 1040 | CD,currentDir |
---|
| 1041 | RETURN |
---|
| 1042 | endif |
---|
| 1043 | ;ignore beta and development build versions of IDL because string to float conversion will fail: |
---|
| 1044 | betaTest=STRPOS(STRLOWCASE(!VERSION.RELEASE),'beta') |
---|
| 1045 | buildTest=STRPOS(STRLOWCASE(!VERSION.RELEASE),'build') |
---|
| 1046 | ;check to make sure the version of IDL running is 5.5 or newer: |
---|
| 1047 | if betaTest EQ -1 and buildTest EQ -1 then begin |
---|
| 1048 | if FLOAT(!VERSION.RELEASE) LT 5.5 then begin |
---|
| 1049 | dummy=dialog_message('IMAGE_VIEWER is only supported in IDL version 5.5 or newer.',/ERROR) |
---|
| 1050 | RETURN |
---|
| 1051 | endif |
---|
| 1052 | endif |
---|
| 1053 | ;check to make sure there is adequate real estate: |
---|
| 1054 | DEVICE,GET_SCREEN_SIZE=screenSize |
---|
| 1055 | if (LONG(screenSize[0])*screenSize[1]) LT 786432 then begin |
---|
| 1056 | messageStr=['IMAGE_VIEWER requires the computer monitor (Display) to be',$ |
---|
| 1057 | 'configured in (1024 x 768) mode or better.'] |
---|
| 1058 | dummy=DIALOG_MESSAGE(messageStr) |
---|
| 1059 | RETURN |
---|
| 1060 | endif |
---|
| 1061 | ;check in auxiliary license: |
---|
| 1062 | result=LMGR("idl_tifflzw",VERSION='1.0') |
---|
| 1063 | result=LMGR("idl_gif",VERSION='1.0') |
---|
| 1064 | gifFlag=1B |
---|
| 1065 | if result NE 1 then begin |
---|
| 1066 | messageStr=['The ability to read GIF (and TIFF LZW compressed) images requires',$ |
---|
| 1067 | 'an auxiliary license in order to conform with the patent rights of the',$ |
---|
| 1068 | 'Unisys Corporation. IMAGE_VIEWER was unable to find the required',$ |
---|
| 1069 | 'license in this installation. Consequently, the ability to read GIF files',$ |
---|
| 1070 | 'will be disabled.'] |
---|
| 1071 | dummy=DIALOG_MESSAGE(messageStr) |
---|
| 1072 | gifFlag=0B |
---|
| 1073 | endif |
---|
| 1074 | ;warn users of color flashing if monitor in PseudoColor mode: |
---|
| 1075 | if !D.N_COLORS LE 256 then begin |
---|
| 1076 | messageStr=['The computer monitor (Display) is currently configured in 8-bit (256 Colors)',$ |
---|
| 1077 | 'PseudoColor mode. Due to the dynamic (read+write) nature of the colormap',$ |
---|
| 1078 | 'system for this visual, when a colortable is loaded for an image it affects',$ |
---|
| 1079 | 'all visible graphics windows, including the thumbnails of other images. This',$ |
---|
| 1080 | 'can lead to a phenomenon known as "color flashing".','',$ |
---|
| 1081 | 'If possible, it is recommended that you exit this program, reconfigure your',$ |
---|
| 1082 | 'monitor in 24-bit (TrueColor) mode or better, and restart IMAGE_VIEWER.'] |
---|
| 1083 | dummy=DIALOG_MESSAGE(messageStr) |
---|
| 1084 | endif |
---|
| 1085 | ;obtain the current working directory: |
---|
| 1086 | CD,CURRENT=currentDir |
---|
| 1087 | if STRUPCASE(!VERSION.OS_FAMILY) EQ 'WINDOWS' then begin |
---|
| 1088 | executeStr='cd "%USERPROFILE%\My Documents\My Pictures" & cd' |
---|
| 1089 | SPAWN,executeStr,pathInit,/HIDE |
---|
| 1090 | pathInit=pathInit[0] |
---|
| 1091 | result=FILE_TEST(pathInit,/READ) |
---|
| 1092 | if result EQ 1 then begin |
---|
| 1093 | CD,pathInit |
---|
| 1094 | endif else begin |
---|
| 1095 | result=FILE_TEST('C:\My Documents\My Pictures',/READ) |
---|
| 1096 | if result EQ 1 then begin |
---|
| 1097 | CD,'C:\My Documents\My Pictures' |
---|
| 1098 | endif else begin |
---|
| 1099 | result=FILE_TEST('C:\',/READ) |
---|
| 1100 | if result EQ 1 then CD,'C:\' |
---|
| 1101 | endelse |
---|
| 1102 | endelse |
---|
| 1103 | endif |
---|
| 1104 | ;suppress informational messaging: |
---|
| 1105 | quietInit=!QUIET |
---|
| 1106 | !QUIET=1 |
---|
| 1107 | ;make sure color decomposition is disabled: |
---|
| 1108 | DEVICE,GET_DECOMPOSED=dc |
---|
| 1109 | if !D.N_COLORS GT 256 then colorMode='TRUE' else colorMode='PSEUDO' |
---|
| 1110 | ;obtain the current color table: |
---|
| 1111 | TVLCT,r,g,b,/GET |
---|
| 1112 | LOADCT,0,/SILENT |
---|
| 1113 | ;force !ORDER=0: |
---|
| 1114 | orderInit=!ORDER |
---|
| 1115 | !ORDER=0 |
---|
| 1116 | ;force !P.BACKGROUND=0: |
---|
| 1117 | backInit=!P.BACKGROUND |
---|
| 1118 | !P.BACKGROUND=0 |
---|
| 1119 | ;create GUI: |
---|
| 1120 | tlb=WIDGET_BASE(TITLE='Image Viewer',/ROW,MBAR=menuBar,/TLB_SIZE_EVENTS,XOFFSET=0,YOFFSET=0) |
---|
| 1121 | fileMenu=WIDGET_BUTTON(menuBar,VALUE='File',/MENU) |
---|
| 1122 | fileBttn1=WIDGET_BUTTON(fileMenu,VALUE='Open Picture Files',EVENT_PRO='image_viewer_open_files') |
---|
| 1123 | fileBttn2=WIDGET_BUTTON(fileMenu,VALUE='Open All In Folder',EVENT_PRO='image_viewer_open_folder') |
---|
| 1124 | fileBttn3=WIDGET_BUTTON(fileMenu,VALUE='Exit',EVENT_PRO='image_viewer_exit') |
---|
| 1125 | helpMenu=WIDGET_BUTTON(menuBar,VALUE='Help',/MENU) |
---|
| 1126 | helpBttn1=WIDGET_BUTTON(helpMenu,VALUE='Help on IMAGE_VIEWER',EVENT_PRO='image_viewer_help') |
---|
| 1127 | controlsBase=WIDGET_BASE(tlb,/COLUMN,/FRAME,/ALIGN_TOP) |
---|
| 1128 | labelBase=WIDGET_BASE(controlsBase,/COLUMN,SCR_XSIZE=280) |
---|
| 1129 | thumbLabel=WIDGET_LABEL(labelBase,/ALIGN_CENTER,VALUE='CLICK ON THUMBNAIL TO VIEW IMAGE') |
---|
| 1130 | thumbBase=WIDGET_BASE(controlsBase,/COLUMN,/ALIGN_TOP,/FRAME,XSIZE=260,YSIZE=700,$ |
---|
| 1131 | /SCROLL,X_SCROLL_SIZE=260,Y_SCROLL_SIZE=650) |
---|
| 1132 | imageBase=WIDGET_BASE(tlb,/COLUMN,/FRAME,/ALIGN_TOP) |
---|
| 1133 | fileBase=WIDGET_BASE(imageBase,/ROW,/ALIGN_CENTER) |
---|
| 1134 | fileLabel=WIDGET_LABEL(fileBase,VALUE='Current Image File = ') |
---|
| 1135 | fileText=WIDGET_TEXT(fileBase,XSIZE=75,YSIZE=1) |
---|
| 1136 | imageDraw=WIDGET_DRAW(imageBase,XSIZE=710,YSIZE=650,RETAIN=2) |
---|
| 1137 | ;display the GUI on the computer monitor: |
---|
| 1138 | WIDGET_CONTROL,tlb,/REALIZE |
---|
| 1139 | ;obtain the top-level base geometry: |
---|
| 1140 | tlbGeom=WIDGET_INFO(tlb,/GEOMETRY) |
---|
| 1141 | tlbWidth=tlbGeom.xsize |
---|
| 1142 | tlbHeight=tlbGeom.ysize |
---|
| 1143 | if tlbWidth EQ 0 or tlbHeight EQ 0 then begin |
---|
| 1144 | WIDGET_CONTROL,tlb,TLB_GET_SIZE=tlbSize |
---|
| 1145 | tlbWidth=tlbSize[0] |
---|
| 1146 | tlbHeight=tlbSize[1] |
---|
| 1147 | endif |
---|
| 1148 | ;create state structure to store information needed by the other event handling procedures: |
---|
| 1149 | pState=PTR_NEW({files:PTR_NEW(/ALLOCATE_HEAP),$ |
---|
| 1150 | images:PTR_NEW(/ALLOCATE_HEAP),$ |
---|
| 1151 | screenSize:screenSize,quietInit:quietInit,orderInit:orderInit,tlb:tlb,statusBase:0L,$ |
---|
| 1152 | controlsBase:controlsBase,thumbBase:thumbBase,fileText:fileText,timer:0B,nFiles:0L,$ |
---|
| 1153 | currentDir:currentDir,imageDraw:imageDraw,dc:dc,r:r,g:g,b:b,gifFlag:gifFlag,statusSlider:0L,$ |
---|
| 1154 | backInit:backInit,colorMode:colorMode,tlbWidth:tlbWidth,tlbHeight:tlbHeight,currFile:0L,$ |
---|
| 1155 | rowBase:0L,increment:0.0}) |
---|
| 1156 | ;store this state structure in the uvalue of the top-level-base |
---|
| 1157 | ;so it can be obtained by other program units: |
---|
| 1158 | WIDGET_CONTROL,tlb,SET_UVALUE=pState |
---|
| 1159 | ;register the GUI with the XMANAGER event handler routine: |
---|
| 1160 | XMANAGER,'image_viewer',tlb,CLEANUP='image_viewer_cleanup' |
---|
| 1161 | END |
---|