Man, I would really like to see a native Tcl implementation of identify. Should be easy.
This is a Tcl/Tk based-GUI to ImageMagick's identify command. This was really my first 'large' Tcl/Tk application, so I would love to see input on how to improve the code and style. This program lets you browse to a file or a directory, and outputs identify's data as tagged XML based upon the options checked.
#!/usr/local/ActiveTcl/bin/wish -f # # idimage.tcl -- # # This file is a Tcl/Tk based GUI for ImageMagick's identify utility. # # RCS: # # $RCSfile: 4277,v $ # $Date: 2006-11-12 19:00:35 $ # $Revision: 1.5 $ package require Tclx package require xmlgen namespace import ::xmlgen::* set run_time [clock format [clock scan now] -format {%D %T} ] # Specify the identify format flag descriptions and flag values. See # http://www.imagemagick.org/script/command-line-options.php#format # for -format flag descriptions and values. set format(File_Size) %b set format(Comment) %c set format(Directory) %d set format(Filename_Extension) %e set format(Filename) %f set format(Unique_Colors) %k set format(Label) %l set format(Magick) %m set format(Number_of_Scenes) %n set format(Output_Filename) %o set format(Page_Number) %p set format(Quantum_Depth) %q set format(Scene_Number) %s set format(Top_of_Filename) %t set format(Temporary_Filename) %u set format(X_Y_Resolution) "%x %y" set format(Geometry) %wx%h set format(Signature) %# # Declare tags used for XML output declaretag Images declaretag Image declaretag Input_Filename # Iterate through format flags and declare tags foreach format_element [array names format] { declaretag $format_element } # Set a title for the window wm title . "Tcl/Tk Identify" # Construct a frame which holds the menubar frame .mbar -relief raised -bd 2 pack .mbar -side top -fill x ####################################### # # Configure the menubar # ####################################### # Top-level menu items: File, Options menubutton .mbar.file -text File -menu .mbar.file.menu -underline 0 menubutton .mbar.options -text Options -menu .mbar.options.menu -underline 0 pack .mbar.file .mbar.options -side left # File menu menu .mbar.file.menu -tearoff 0 .mbar.file.menu add command -label Open -underline 0 -accelerator "Ctrl+O" \ -command "file_dialog" .mbar.file.menu add command -label "Identify All" -underline 9 -accelerator \ "Ctrl+A" -command "dir_dialog" .mbar.file.menu add command -label Quit -underline 0 -accelerator "Ctrl+Q" \ -command exit # Keyboard shortcuts for file menu options bind all <Control-o> {file_dialog} bind all <Control-a> {dir_dialog} bind all <Control-q> {exit} # Options menu menu .mbar.options.menu -tearoff 1 # Populate the options menu foreach format_element [array names format] { # Substitute " " for "_" for display in options menu regsub -all "_" $format_element " " gui_format_element .mbar.options.menu add checkbutton -label "$gui_format_element" -variable \ $format_element } ####################################### # # Text widget to display output # ####################################### text .text -relief flat -bd 2 -yscrollcommand ".scroll set" -font \ -adobe-courier-medium-r-*-*-12-*-*-*-*-*-*-* # Enable gridding in the text widget .text configure -setgrid 1 scrollbar .scroll -command ".text yview" pack .scroll -side right -fill y # Pack the text widget so it fills both axes and will expand to fill screen pack .text -side left -fill both -expand 1 # Procedure: file_dialog -- # # Produce a dialog box that will allow the user open an individual file. # # Arguments: # None # # Results: # Passes a file name to the identify_file procedure. proc file_dialog {} { # This is used as an attribute value for the Images tag global run_time set types { {{All Files} {*}} } set file [tk_getOpenFile -filetypes $types] if {$file != ""} { # Clear contents of text area .text delete 0.0 end set id_out [identify_file $file] set xml_out [Images date=$run_time $id_out] .text insert end $xml_out } } # Procedure: identify_file -- # # Execute identify using the user designated options and show the results in # the text widget. # # Arguments: # Name of file to identify. # # Results: # Identify results written to text widget. proc identify_file {thisfile} { set flags [identify_options] set result [catch {exec identify -format "$flags" $thisfile} msg] if {$result==0} { set id_out [Image $msg] return $id_out } else { # An error has occurred, so inform user and continue .text insert end "An exception has occurred:\n$msg" } } # Procedure: identify_options -- # # Creates a string of -format flags based upon what the user checks in the # Options menu. # # Arguments: # None # # Results: # A string of -format flags and additional formatting elements. proc identify_options {} { # Make format array available to this proc global format # Input filename is the default flag set flags " [Input_Filename {%i}]\n" foreach format_element [array names format] { global $format_element set format_element_checked $$format_element regsub -all "_" $format_element " " gui_format_element if [expr $format_element_checked] { append flags [$format_element $format($format_element)]\n } } return $flags } # Procedure: dir_dialog -- # # Open a directory chooser dialog box # # Arguments: # None # # Results: # A directory name passed to the identify_all procedure. proc dir_dialog {} { set dir [tk_chooseDirectory -mustexist 1] if {$dir != ""} { # Clear contents of text area .text delete 0.0 end # Readdir puts the names of all files in the target dir in a list. set files [readdir $dir] identify_all $dir $files } } # Procedure: identify_all -- # # # # Arguments: # A directory name. # # Results: # Pass each filename within the target directory to the identify_file # procedure. proc identify_all {dir files} { # This is used as an attribute value for the Images tag global run_time # Identify each file and append results to id_out foreach file $files { append id_out [identify_file $dir/$file] } set xml_out [Images date=$run_time $id_out] .text insert end $xml_out }