#!/usr/bin/perl -I/usr/lib/perl5/site_perl -w # 如果需要完整的顏色轉換程式, 請至 CPAN 下載 Image::Colorimetry 模組. use strict; sub HSBtoRGB { # "Computer Graphics: Principles and Practice" Foley, Van Dam, Feiner, Hughes my ($h, $s, $b) = @_; my ($i, $f); $h = $h - int($h); $h = $h * 6; $i = int($h); $f = $h - $i; my ($p, $q, $t) = ($b*(1-$s), $b*(1-$s*$f), $b*(1-$s*(1-$f))); return $i == 0 ? ($b, $t, $p) : $i == 1 ? ($q, $b, $p) : $i == 2 ? ($p, $b, $t) : $i == 3 ? ($p, $q, $b) : $i == 4 ? ($t, $p, $b) : $i == 5 ? ($b, $p, $q) : die("strange?"); } # use vars qw($PI $sin60); # # BEGIN { # $PI = atan2(1,1) * 4; # $sin60 = sin($PI/3); # } # # # http://www.prip.tuwien.ac.at/~hanbury/CVWW02.pdf # sub RGBtoHSB { # my ($r, $g, $b) = @_; # my ($y, $c1, $c2, $chrome, $h, $hstar); # $y = 0.2125*$r + 0.7154*$g + 0.0721*$b; # $c1 = $r - 0.5*$g - 0.5*$b; # $c2 = - 0.8860*$g + 0.8860*$b; # $chrome = sqrt($c1*$c1 + $c2*$c2); # $h = atan2($c2, $c1); # $h /= 2 * $PI; # $h += 1 if $h < 0; # $hstar = $h * 6; # $hstar -= int($hstar); # my ($s) = $chrome*sin($PI/3*(2 - $hstar))/$sin60; # return ($h, $s, $y); # } # # # Inverse is difficult to calculate. # # First use hue and brightness to find a ray. # # Intersect this ray with one of the 6 faces of the cube. # # Somewhere between the achromatic axis to the intersection # # point lies the answer. The distance is determined by saturation. # # The following code is too simplistic and is incorrect. # sub HSBtoRGB { # my ($h, $s, $y) = @_; # my ($hstar, $chrome, $c1, $c2); # $hstar = $h * 6; # $hstar -= int($hstar); # $chrome = $s * $sin60 / sin($PI/3*(2 - $hstar)); # $h *= 2 * $PI; # $c1 = $chrome * cos($h); $c2 = $chrome * sin($h); # my ($r, $g, $b) = ( # $y+0.7875*$c1+0.371409*$c2, # $y-0.2125*$c1-0.205941*$c2, # $y-0.2125*$c1+0.94876*$c2 # ); # return ($r, $g, $b); # } # # if (0) { # my ($i, @ans); # for ($i=0; $i<6; ++$i) { # printf "hsb(%f,1,1) ==> ", $i/6.0; # @ans = HSBtoRGB($i/6.0,1,1); # printf "rgb(%f,%f,%f) ==> ", @ans; # printf "hsb(%f,%f,%f)\n", RGBtoHSB(@ans); # } # } 1;