Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Re: Convert RGB to an actual color

by Zaxo (Archbishop)
on Nov 20, 2002 at 05:12 UTC ( #214357=note: print w/replies, xml ) Need Help??


in reply to Convert RGB to an actual color

I read this to say you want to obtain color names for nearby rgb values. Is that correct? Assuming so, GD can give you a great deal of help. I'll go over how to produce a new copy of an image from a restricted set of colors, and the names will fall right out.

Declare we will make use of GD objects and define a function to return the index of a GD object's palette color from an rgb triple, allocating a new color if necessary:

use GD; sub getindex { my $image = shift; my $index = $image->colorExact(@_); $index == -1 ? $image->colorAllocate(@_) : $index; }
Here lets read all the named colors from /usr/X11/lib/X11/rgb.txt and provide them to a reference GD image's color table:
my $reference_image = new GD::Image(100,100); my @colornames; { my $goodline = qr/^\d/; open my $rgbdat, '<', '/usr/X11/lib/X11/rgb.txt' or die $!; while (<$rgbdat>) { /$goodline/ or next; my @dat = split " ", $_, 4; my $color = pop @dat; $colornames[getindex($reference_image, @dat)] = $color; } close $rgbdat or die $!; }
Now read the jpeg file into a GD::Image
my $image = GD::Image->newFromJpeg('many.jpg') or die $!; my @size = $image->Bounds();
Start a new GD::Image to be built with only named colors my $new_image = GD::Image->new @size;
and fill it in
{ my ($ix, $iy, @rgb); # preallocate and reuse for $ix (0 .. $size[0]-1) { for $iy (0 .. $size[1]-1) { @rgb = $image->rgb(image->getPixel($ix,$iy))); @rgb = $reference_image->rgb( $reference_image->colorClose +stHWB( @rgb )); $new_image->setPixel($ix, $iy, getindex($new_image, @rgb)) +; } } }
The new image's colors are obtained by grabbing the pixel's rgb color, finding the closest reference color's rgb values, and setting the corresponding pixel in the new image, allocating the named color to the new palette if necessary.

We can define a function to return the name of the nearest color, given an rgb pair, but as this code is written there is a closure with $reference_image and @colornames. It would be better to put the reference structures in a module, or case them up in constants with initialization in a BEGIN{} block.

sub getcolor { return "puke" unless @_ == 3; $colornames[$reference_image->colorClosestHWB(@_)] }

You'll notice that GD provided all the heavy lifting for this. Have fun!

After Compline,
Zaxo

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://214357]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (3)
As of 2019-07-20 07:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?