Skip to content

Instantly share code, notes, and snippets.

@kiyotakagoto
Created December 8, 2011 10:40
Show Gist options
  • Save kiyotakagoto/1446679 to your computer and use it in GitHub Desktop.
Save kiyotakagoto/1446679 to your computer and use it in GitHub Desktop.
RGBからHSVに変換する(perl)
package RGBtoHSV;
use strict;
use warnings;
sub rgb_to_hsv {
my $rgb_ref = shift;
my $max_c = get_max( $rgb_ref );
my $min_c = get_min( $rgb_ref );
if ( is_white($rgb_ref) ) {
return {
H => 0,
S => 0,
V => 255,
};
}
elsif ( is_black($rgb_ref) ) {
return {
H => 0,
S => 0,
V => 0,
};
}
else {
return get_hsv_from_rgb( $rgb_ref, $max_c, $min_c );
}
}
sub is_black {
my $rgb_ref = shift;
if ( 0 == $rgb_ref->{R} && 0 == $rgb_ref->{G} && 0 == $rgb_ref->{B} ) {
return 1;
}
else {
return;
}
}
sub is_white {
my $rgb_ref = shift;
if ( 255 == $rgb_ref->{R} && 255 == $rgb_ref->{G} && 255 == $rgb_ref->{B} ) {
return 1;
}
else {
return;
}
}
sub get_hsv_from_rgb {
my $rgb_ref = shift;
my $max_c = shift;
my $min_c = shift;
return {
H => calc_H( $rgb_ref, $max_c, $min_c ),
S => calc_S( $rgb_ref, $max_c, $min_c ),
V => calc_V( $rgb_ref, $max_c ),
};
}
sub calc_H {
my ($rgb_ref, $max_c, $min_c) = @_;
my ($R, $G, $B, $MAX, $MIN) = ( $rgb_ref->{R}, $rgb_ref->{G}, $rgb_ref->{B}, $rgb_ref->{$max_c}, $rgb_ref->{$min_c} );
my $H
= $max_c eq 'R' ? 60 * ( ($G - $B) / ($MAX - $MIN) ) + 0
: $max_c eq 'G' ? 60 * ( ($B - $R) / ($MAX - $MIN) ) + 120
: 60 * ( ($R - $G) / ($MAX - $MIN) ) + 240
;
return $H < 0 ? $H + 360
: $H
;
}
sub calc_S {
my ($rgb_ref, $max_c, $min_c) = @_;
return ( $rgb_ref->{$max_c} - $rgb_ref->{$min_c} ) / $rgb_ref->{$max_c};
}
sub calc_V {
my ($rgb_ref, $max_c) = @_;
return $rgb_ref->{$max_c} / 255;
}
sub get_max {
my $rgb_ref = shift;
my $max = 0;
my $max_name = '';
while ( my ( $cname, $value ) = each( %$rgb_ref ) ) {
if ( $value > $max ) {
$max = $value;
$max_name = $cname;
}
}
return $max_name;
}
sub get_min {
my $rgb_ref = shift;
my $min = 2000000000;
my $min_name = '';
while ( my ( $cname, $value ) = each( %$rgb_ref ) ) {
if ( $value < $min ) {
$min = $value;
$min_name = $cname;
}
}
return $min_name;
}
1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment