package RGB; use strict; sub new { my ($class, $input) = @_; my $self = {}; $self->{RGB} = []; bless($self); $self->init($input); return $self; } sub init { my ($self, $input) = @_; if ($input =~ /^\#/) { $self->hex($input); } else { $self->rgb($input); } } sub hex { my ($self, $hex) = @_; if ($hex) { $self->{RGB} = hex_to_rgb($hex); } return rgb_to_hex($self->{RGB}); } sub rgb { my ($self, $rgb) = @_; if (ref($rgb) eq "ARRAY") { $self->{RGB} = $rgb; } return $self->{RGB}; } sub hex_to_rgb { my ($hex) = @_; $hex =~ s/^\#//; my ($r, $g, $b); if (length($hex) == 6) { $r = hex(substr($hex, 0, 2)); $g = hex(substr($hex, 2, 2)); $b = hex(substr($hex, 4, 2)); } elsif (length($hex) == 3) { $r = hex(substr($hex, 0, 1) x 2); $g = hex(substr($hex, 1, 1) x 2); $b = hex(substr($hex, 2, 1) x 2); } return [$r, $g, $b]; } sub rgb_to_hex { my ($rgb) = @_; for (my $i = 0; $i < 3; $i++) { $rgb->[$i] = 255 if $rgb->[$i] > 255; $rgb->[$i] = 0 if $rgb->[$i] < 0; } return sprintf ("#%02X%02X%02X", @{$rgb}); } sub display_rgb { my ($self) = @_; my $out = join ", ", map {int $_} @{ $self->{RGB} }; $out = "rgb(".$out.")"; return $out; } sub display_hex { my ($self) = @_; return $self->hex(); } sub add { my ($self, $fuzz) = @_; $fuzz = parse_fuzz($fuzz); for (my $i = 0; $i < 3; $i++) { $self->{RGB}->[$i] += $fuzz->[$i]; } } sub mollify { my ($self, $fuzz) = @_; $fuzz = parse_fuzz($fuzz); for (my $i = 0; $i < 3; $i++) { my $offset = int( rand($fuzz->[$i] + 1) ); $self->{RGB}->[$i] += $offset; } } sub perturb { my ($self, $fuzz) = @_; $fuzz = parse_fuzz($fuzz); for (my $i = 0; $i < 3; $i++) { my $offset = int( rand($fuzz->[$i] + 1) - ( $fuzz->[$i] / 2 ) ); $self->{RGB}->[$i] += $offset; } } sub parse_fuzz { my ($fuzz) = @_; if (ref($fuzz) eq "RGB") { $fuzz = $fuzz->rgb(); } elsif (ref($fuzz) eq "ARRAY") { } else { $fuzz = [$fuzz, $fuzz, $fuzz]; } return $fuzz; } sub clip { my ($self) = @_; for (my $i = 0; $i < 3; $i++) { $self->{RGB}->[$i] = 255 if $self->{RGB}->[$i] > 255; $self->{RGB}->[$i] = 0 if $self->{RGB}->[$i] < 0; } } sub rgb_map { my ($self, $func, $a, $b) = @_; my ($ra) = $a->rgb(); my ($rb) = $b->rgb(); my (@rgb) = map { &{$func}($ra->[$_], $rb->[$_]) } 0,1,2; return RGB->new(\@rgb); } 1;