green:
blue:
red:
achromatic:
yellow:
cyan:
magenta:
Hue / red distance:
Code:
#!perl -w
use Graphics::ColorObject;
use Math::Trig;
use strict;
use warnings;
use List::Util qw/min max/;
use Data::Dumper;
use URI;
use HTML::Entities qw/encode_entities_numeric/;
use GD;
sub mk {
Graphics::ColorObject->new_RGB255(\@_)->as_Lab;
}
my %ref = (
# black => mk(0,0,0),
# white => mk(255,255,255),
achromatic => mk(127,127,127),
red => mk(255,0,0),
# rose => mk(255,0,127),
magenta => mk(255,0,255),
# violet => mk(127,0,255),
blue => mk(0,0,255),
# azure => mk(0, 127, 255),
cyan => mk(0,255,255),
# spring => mk(0,255,127),
green => mk(0,255,0),
# chartreuse => mk(127,255,0),
yellow => mk(255,255,0),
# orange => mk(255,127,0),
# brown => mk(150, 75, 0),
);
sub distance {
my ($ref, $cur) = @_;
sqrt(($cur->[0] - $ref->[0])**2 +
($cur->[1] - $ref->[1])**2 +
($cur->[2] - $ref->[2])**2);
}
my %m;
my $image = GD::Image->new(360, 360, 1);
$image->saveAlpha(1);
$image->trueColor(1);
for (0..2**16) {
my $r = int (rand() * 255);
my $g = int (rand() * 255);
my $b = int (rand() * 255);
my $obj = Graphics::ColorObject->new_RGB255([$r, $g, $b]);
my $cur = $obj->as_Lab;
my $hue = $obj->as_HSL->[0];
my $col = (($r) << 16) + (($g) << 8) + (($b) << 0);
if (rand() < 0.2) {
my %dis = map { distance($ref{$_}, $cur) => $_ } keys %ref;
my $min = $dis{ min(keys %dis) };
$m{$min}->{$col}++;
}
my $rdi = distance($ref{red}, $cur);
my $x = 180 + $rdi * cos($hue);
my $y = 180 + $rdi * sin($hue);
$image->setPixel($x, $y, $image->colorAllocate($r, $g, $b));
}
sub mk2 {
Graphics::ColorObject->new_RGB255([
map { $_ & 0xFF } ($_[0] >> 16, $_[0] >> 8, $_[0] >> 0)
])->as_Lab;
}
foreach my $bucket (keys %m) {
printf "<p>%s: ", $bucket;
foreach my $col (sort {
distance($ref{$bucket}, mk2 $a) <=> distance($ref{$bucket}, mk2 $b)
} keys %{ $m{$bucket} }) {
printf "<i style='background-color: #%06x'>  </i>", $col
}
}
my $data = URI->new("data:image/png,");
$data->data($image->png(9));
printf "<p>Hue / red distance: <img alt='...' src='%s'>\n",
encode_entities_numeric($data);
my $file = do { local$/; IO::File->new('<1.pl')->getline };
printf "<p>Code:<pre>%s",
encode_entities_numeric($file);
print "</pre>";