ulis A proc to display or export the colors histogram of a photo image.
I was interested to compare the histogram of a reduced image with the histogram of the original image.
The proc counts the occurrence of each color component (RGB) for all of the image colors.
namespace eval ::histo { namespace export histo package require Tk proc histo {image {cmd -display}} { # get options switch -glob -- $cmd { -dis* { set cmd -display } -exp* { set cmd -export } default { error "use\n\t[histo image ?-display|-export?" } } # get the image size set width [image width $image] set height [image height $image] if {$width * $height == 0} { error "bad image" } # count colors components for {set i 0} {$i < 256} {incr i} { foreach c {r g b} { set counts($c:$i) 0 } } set max 0 for {set y 0} {$y < $height} {incr y} { for {set x 0} {$x < $width} {incr x} { foreach {r g b} [$image get $x $y] break foreach c {r g b} { set n [incr counts($c:[set $c])] if {$max < $n} { set max $n } } } } if {$cmd == "-display"} { # display # compute the coef set coef [expr {256.0 / $max}] # create toplevel set t _$image toplevel .$t wm title .$t $image # draw the histogram set c .$t.c canvas $c -width [expr {256 * 3 + 40}] -height [expr {256 + 40}] set x0 9 set y0 267 $c create rectangle $x0 9 [incr x0 258] $y0 \ -outline black -fill white incr x0 8 $c create rectangle $x0 9 [incr x0 258] $y0 \ -outline black -fill white incr x0 8 $c create rectangle $x0 9 [incr x0 258] $y0 \ -outline black -fill white set y1 272 set x0 10 for {set i 0} {$i < 17} {incr i} { $c create line $x0 $y0 $x0 $y1 incr x0 16 } set x0 276 for {set i 0} {$i < 17} {incr i} { $c create line $x0 $y0 $x0 $y1 incr x0 16 } set x0 542 for {set i 0} {$i < 17} {incr i} { $c create line $x0 $y0 $x0 $y1 incr x0 16 } incr y0 -1 set xr 10 set xg 276 set xb 542 for {set i 0} {$i < 256} {incr i} { set yr [expr {10 + 256 - round($counts(r:$i) * $coef)}] set yg [expr {10 + 256 - round($counts(g:$i) * $coef)}] set yb [expr {10 + 256 - round($counts(b:$i) * $coef)}] $c create line $xr $y0 $xr $yr -fill red $c create line $xg $y0 $xg $yg -fill green $c create line $xb $y0 $xb $yb -fill blue incr xr; incr xg; incr xb } $c create text 10 276 -anchor nw \ -text "image: $image, max count: $max" pack $c } else { # export for {set i 0} {$i < 256} {incr i} { foreach c {r g b} { lappend list$c $counts($c:$i) } } return [list $listr $listg $listb] } } }
# example # ----------- # to download the image: # http://perso.wanadoo.fr/maurice.ulis/tcl/image1.png package require Tk package require Img wm withdraw . namespace import ::histo::histo histo [image create photo -file image1.png]
See also