Update: D'oh, I missed the "Websafe" requirement (people still worry about that?) -- Feel free to ignore me...
I have code which does this using Color::Calc.
# Example usage:
say for colors(distribute => 1, format=> "hex", n => 10, colors => [qw
+/red yellow green/]);
=head3 colors
At the most basic level, converts colors to different formats, however
+ this
subroutine is capable of quite a bit more than that.
Examples:
colors [qw/red green blue/], format => "ps";
colors [qw/red green blue/], format => "ps", n => 2;
=over 4
=item colors
A list of colors, can be an X11 color name or any of the other formats
recognised by Color::Calc.
=item n
Only return n colors.
=item interpolate
If false, requesting more colors than available in the colors list wil
+l
throw a fatal error. The default is to create new colors between the g
+iven
colors if there are insufficient colors provided. The interpolate comm
+and
will also cause colors to be interpolated if the distribute option is
+set.
=item distribute
By default, if fewer colors are requested than are contained in the co
+lors
list, this subroutine will select the first n colors. Providing a true
value for distribute will cause the subroutine to evenly spread out th
+e
choice of colors over the range of colors provided (if n E<gt> 2 then
+the
first and last colors are guaranteed to be included).
=item format
Specify the style of the returned colors. Can be anything supported by
Color::Calc which is currently (Color::Calc::VERSION == 1.0): "tuple",
"hex", "html", "object" (a Graphics::ColorObject object), "pdf". The
default format is "object".
The following formats are also accepted and are handled by this subrou
+tine
directly: "ps" | "postscript".
=item background
Try to make the colors appear on the given background color. Colors B<
+will>
be altered if this option is provided.
=back
=cut
#BEGIN: colors
sub colors {
require Color::Calc;
unshift @_, "colors" if @_ % 2;
my %o = @_;
my $c = $o{colors};
my $n = $o{n} ||= @$c;
$o{interpolate} = 1 unless exists $o{interpolate};
croak "Not enough "."colors in plot color database" unless $o{interp
+olate} or $n <= @$c;
$o{format} ||= 'object';
$o{format} = lc $o{format};
@o{qw/format _format/} = qw/tuple ps/ if $o{format} =~ /^(?:ps|posts
+cript)$/;
my $cct = Color::Calc->new( 'ColorScheme' => 'X', OutputFormat => 't
+uple' );
my $cc = Color::Calc->new( 'ColorScheme' => 'X', OutputFormat => $o
+{format} );
$o{listed} = 1 if $o{format} eq 'tuple';
if (($n > @$c) or ($o{distribute} and $o{interpolate})) {
$c = [map [($_==int($_))?$$c[$_]:$cct->mix($$c[int $_],$$c[int($_)
++1], $_-int($_))], map +($_*($#{$c})/(($n-1)||1)), 0..$n-1];
} elsif ($o{distribute} and $n < @$c) {
$c = [map $$c[int($_*($#{$c})/(($n-1)||1))], 0..$n-1];
}
if ($o{background}) {
my $fg = $cc->contrast_bw($o{background});
if ($o{listed}) {
$c = [ map [$cc->mix($_, $fg, .35)], @$c[0..$n-1] ];
} else {
$c = [ map $cc->mix($_, $fg, .35), @$c[0..$n-1] ];
}
} else {
if ($o{listed}) {
$c = [ map [$cc->get($_)], @$c[0..$n-1] ];
} else {
$c = [ map $cc->get($_), @$c[0..$n-1] ];
}
}
if ($o{_format}) {
$o{_format} eq 'ps' and do { for (@$c) { $_ /= 255 for @$_ } };
}
return wantarray ? @$c : $c;
}
#END: colors
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.