This commit is contained in:
root
2025-11-07 11:31:06 +00:00
commit 2859f93882
407 changed files with 99769 additions and 0 deletions

152
lib/Smokeping/Colorspace.pm Normal file
View File

@@ -0,0 +1,152 @@
# -*- perl -*-
package Smokeping::Colorspace;
=head1 NAME
Smokeping::Colorspace - Simple Colorspace Conversion methods
=head1 OVERVIEW
This module provides simple colorspace conversion methods, primarily allowing
conversion from RGB (red, green, blue) to and from HSL (hue, saturation, luminosity).
=head1 COPYRIGHT
Copyright 2006 by Grahame Bowland.
=head1 LICENSE
This program is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public
License along with this program; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
02139, USA.
=head1 AUTHOR
Grahame Bowland <grahame.bowland@uwa.edu.au>
=cut
sub web_to_rgb {
my $web = shift;
$web =~ s/^#//;
my @rgb = (hex(substr($web, 0, 2)) / 255,
hex(substr($web, 2, 2)) / 255,
hex(substr($web, 4, 2)) / 255) ;
return @rgb;
}
sub rgb_to_web {
my @rgb = @_;
return sprintf("#%.2x%.2x%.2x", 255 * $rgb[0], 255 * $rgb[1], 255 * $rgb[2]);
}
sub min_max_indexes {
my $idx = 0;
my ($min_idx, $min, $max_idx, $max);
my @l = @_;
foreach my $i (@l) {
if (not defined($min) or ($i < $min)) {
$min = $i;
$min_idx = $idx;
}
if (not defined($max) or ($i > $max)) {
$max = $i;
$max_idx = $idx;
}
$idx++;
}
return ($min_idx, $min, $max_idx, $max);
}
# source for conversion algorithm is:
# http://www.easyrgb.com/math.php?MATH=M18#text18
sub rgb_to_hsl {
my @rgb = @_;
my ($h, $l, $s);
my ($min_idx, $min, $max_idx, $max) = min_max_indexes(@rgb);
my $delta_max = $max - $min;
$l = ($max + $min) / 2;
if ($delta_max == 0) {
my $h = 0;
my $s = 0;
} else {
if ($l < 0.5) {
$s = $delta_max / ($max + $min);
} else {
$s = $delta_max / (2 - $max - $min);
}
my $delta_r = ((($max - $rgb[0]) / 6) + ($max / 2)) / $delta_max;
my $delta_g = ((($max - $rgb[1]) / 6) + ($max / 2)) / $delta_max;
my $delta_b = ((($max - $rgb[2]) / 6) + ($max / 2)) / $delta_max;
if ($max_idx == 0) {
$h = $delta_b - $delta_g;
} elsif ($max_idx == 1) {
$h = (1/3) + $delta_r - $delta_b;
} else {
$h = (2/3) + $delta_g - $delta_r;
}
if ($h < 0) {
$h += 1;
} elsif ($h > 1) {
$h -= 1;
}
}
return ($h, $s, $l);
}
sub hue_to_rgb {
my ($v1, $v2, $vh) = @_;
if ($vh < 0) {
$vh += 1;
} elsif ($vh > 1) {
$vh -= 1;
}
if ($vh * 6 < 1) {
return $v1 + ($v2 - $v1) * 6 * $vh;
} elsif ($vh * 2 < 1) {
return $v2;
} elsif ($vh * 3 < 2) {
return $v1 + ($v2 - $v1) * ((2/3) - $vh) * 6;
} else {
return $v1;
}
}
sub hsl_to_rgb {
my ($h, $s, $l) = @_;
my ($r, $g, $b);
if ($s == 0) {
$r = $g = $b = $l;
} else {
my $ls;
if ($l < 0.5) {
$ls = $l * (1 + $s);
} else {
$ls = ($l + $s) - ($s * $l);
}
$l = 2 * $l - $ls;
$r = hue_to_rgb($l, $ls, $h + 1/3);
$g = hue_to_rgb($l, $ls, $h);
$b = hue_to_rgb($l, $ls, $h - (1/3));
}
return ($r, $g, $b);
}
1;