Version 0 of HSV and RGB

Updated 2007-07-11 20:45:48 by Googie

HSV and RGB are defines color spaces. HSV stands for Hue, Saturation, Value, while RGB stands for Red, Green, Blue. This page provides way(s) to convert values betwean these two color formates.

Googie 11.07.2007 - The code below uses only math package from tcllib, so it's fully portable. It implements routines described on Wikipedia [L1 ].

 package require math

 proc rgbToHsv {r g b} {
         set temp [math::min $r $g $b]
         set v [math::max $r $g $b]
         set value $v
         set bottom [expr {$v-$temp}]
         if {$bottom == 0} {
                 set hue 0
                 set saturation 0
                 set value $v
         } else {
                 if {$v == $r} {
                         set top [expr {$g-$b}]
                         if {$g >= $b} {
                                 set angle 0
                         } else {
                                    set angle 360
                         }
                 } elseif {$v == $g} {
                         set top [expr {$b-$r}]
                         set angle 120
                 } elseif {$v == $b} {
                         set top [expr {$r-$g}]
                         set angle 240
                 }
                 set hue [expr { round( 60 * ( double($top) / $bottom ) + $angle ) }]
         }

         if {$v == 0} {
                 set saturation 0
         } else {
                 set saturation [expr { round( 255 - 255 * ( double($temp) / $v ) ) }]
         }
         return [list $hue $saturation $value]
 }

 proc hsvToRgb {h s v} {
         set Hi [expr { int( double($h) / 60 ) % 6 }]
         set f [expr { double($h) / 60 - $Hi }]
         set s [expr { double($s)/255 }]
         set v [expr { double($v)/255 }]
         set p [expr { double($v) * (1 - $s) }]
         set q [expr { double($v) * (1 - $f * $s) }]
         set t [expr { double($v) * (1 - (1 - $f) * $s) }]
         switch -- $Hi {
                 0 {
                         set r $v
                         set g $t
                         set b $p
                 }
                 1 {
                         set r $q
                         set g $v
                         set b $p
                 }
                 2 {
                         set r $p
                         set g $v
                         set b $t
                 }
                 3 {
                         set r $p
                         set g $q
                         set b $v
                 }
                 4 {
                         set r $t
                         set g $p
                         set b $v
                 }
                 5 {
                         set r $v
                         set g $p
                         set b $q
                 }
                 default {
                         error "Wrong Hi value in hsvToRgb procedure! This should never happen!"
                 }
         }
         set r [expr {round($r*255)}]
         set g [expr {round($g*255)}]
         set b [expr {round($b*255)}]
         return [list $r $g $b]
 }

 # Demo
 set r 100
 set g 200
 set b 150
 foreach {h s v} [rgbToHsv $r $g $b] {}
 puts "rgb: $r $g $b -> hsv: $h $s $v"
 puts "back to hsv: [hsvToRgb $h $s $v]"