[rt.cpan.org #65385] Patch for Imager::Color->hsv
authorPhilip Gwyn <perl@pied.nu>
Thu, 3 Feb 2011 07:21:05 +0000 (18:21 +1100)
committerTony Cook <tony@develop-help.com>
Thu, 3 Feb 2011 07:21:05 +0000 (18:21 +1100)
lib/Imager/Color.pm
t/t15color.t

index 9bad143e4cc0579ef9d53f577d71a72e19f12d1c..b966f17b1cef2ba1273f4fe4ea2aa93939ab97fc 100644 (file)
@@ -393,6 +393,59 @@ sub equals {
 
 sub CLONE_SKIP { 1 }
 
 
 sub CLONE_SKIP { 1 }
 
+# Lifted from Graphics::Color::RGB 
+# Thank you very much
+sub hsv {
+    my( $self ) = @_;
+
+    my( $red, $green, $blue, $alpha ) = $self->rgba;
+    my $max = $red;
+    my $maxc = 'r';
+    my $min = $red;
+
+    if($green > $max) {
+        $max = $green; 
+        $maxc = 'g';   
+    }
+    if($blue > $max) {
+        $max = $blue; 
+        $maxc = 'b';  
+    }
+
+    if($green < $min) {
+        $min = $green; 
+    }
+    if($blue < $min) {
+        $min = $blue; 
+    }
+
+    my ($h, $s, $v);
+
+    if($max == $min) {
+        $h = 0;
+    } 
+    elsif($maxc eq 'r') {
+        $h = 60 * (($green - $blue) / ($max - $min)) % 360;
+    } 
+    elsif($maxc eq 'g') {
+        $h = (60 * (($blue - $red) / ($max - $min)) + 120);
+    } 
+    elsif($maxc eq 'b') {
+        $h = (60 * (($red - $green) / ($max - $min)) + 240);
+    }
+
+    $v = $max/255;
+    if($max == 0) {
+        $s = 0;
+    } 
+    else {
+        $s = 1 - ($min / $max);
+    }
+
+    return int($h), $s, $v, $alpha;
+
+}
+
 1;
 
 __END__
 1;
 
 __END__
@@ -414,7 +467,7 @@ Imager::Color - Color handling for Imager.
   $color->set("#C0C0FF"); # html color specification
 
   ($red, $green, $blue, $alpha) = $color->rgba();
   $color->set("#C0C0FF"); # html color specification
 
   ($red, $green, $blue, $alpha) = $color->rgba();
-  @hsv = $color->hsv(); # not implemented but proposed
+  @hsv = $color->hsv();
 
   $color->info();
 
 
   $color->info();
 
@@ -620,6 +673,14 @@ These color specifications can be used for both constructing new
 colors with the new() method and modifying existing colors with the
 set() method.
 
 colors with the new() method and modifying existing colors with the
 set() method.
 
+=head1 METHODS
+
+=head2 hsv
+
+    my($h, $s, $v, $alpha) = $colour->hsv();
+
+Returns the colour as a Hue/Saturation/Value/Alpha tuple.
+
 =head1 AUTHOR
 
 Arnar M. Hrafnkelsson, addi@umich.edu
 =head1 AUTHOR
 
 Arnar M. Hrafnkelsson, addi@umich.edu
index bed1a0174c5f0cacbfc4fc6464ba425b2e296457..7b03dc41e8d607935f13a6b82fb45aa8739a73a9 100644 (file)
@@ -7,7 +7,7 @@
 # Change 1..1 below to 1..last_test_to_print .
 # (It may become useful if the test is moved to ./t subdirectory.)
 
 # Change 1..1 below to 1..last_test_to_print .
 # (It may become useful if the test is moved to ./t subdirectory.)
 
-use Test::More tests => 55;
+use Test::More tests => 70;
 
 use Imager;
 use Imager::Test qw(is_fcolor4);
 
 use Imager;
 use Imager::Test qw(is_fcolor4);
@@ -156,6 +156,39 @@ color_ok('builtin black', 0, 0, 0, 255,
   ok(!$c->set("-unknown-"), "set to unknown");
 }
 
   ok(!$c->set("-unknown-"), "set to unknown");
 }
 
+{
+  # test ->hsv
+  my $c = Imager::Color->new(255, 0, 0);
+  my($h,$s,$v) = $c->hsv;
+  is($h,0,'red hue');
+  is($s,1,'red saturation');
+  is($v,1,'red value');
+
+  $c = Imager::Color->new(0, 255, 0);
+  ($h,$s,$v) = $c->hsv;
+  is($h,120,'green hue');
+  is($s,1,'green saturation');
+  is($v,1,'green value');
+
+  $c = Imager::Color->new(0, 0, 255);
+  ($h,$s,$v) = $c->hsv;
+  is($h,240,'blue hue');
+  is($s,1,'blue saturation');
+  is($v,1,'blue value');
+
+  $c = Imager::Color->new(255, 255, 255);
+  ($h,$s,$v) = $c->hsv;
+  is($h,0,'white hue');
+  is($s,0,'white saturation');
+  is($v,1,'white value');
+
+  $c = Imager::Color->new(0, 0, 0);
+  ($h,$s,$v) = $c->hsv;
+  is($h,0,'black hue');
+  is($s,0,'black saturation');
+  is($v,0,'black value');
+}
+
 sub test_col {
   my ($c, $r, $g, $b, $a) = @_;
   unless ($c) {
 sub test_col {
   my ($c, $r, $g, $b, $a) = @_;
   unless ($c) {