Perl: October 2010 Archives

Mapping terminal colors

| Comments | No TrackBacks

Recently I started to work more intensively under Windows. Being a Linux convert, I installed MSYS to have bash and other UN*X tools. Although MSYS works nice, I had problems with proper console behavior. Both the Windows default one (cmd.exe) and Console2 lack some terminal capabilities, so I stick with MSYS’ rxvt.

One thing I didn’t like about rxvt was the colors. I have Tango colors set in Gnome Terminal, so I tried to copy the palette.

Rxvt allows you to set an ANSI color with -colorX options, but accepts only X11 color names, while Gnome Terminal gives you RGB values.

So I wrote a simple script which reads an RGB triple from the input and finds the closest matching colors in the palette. Here it is:

use warnings;
use strict;

use 5.010;
use Color::Similarity::HCL qw( distance );

my ($fname) = @ARGV;
die "Usage: $0 /etc/X11/rgb.txt" unless defined $fname;

my @palette;
open my $xcol_fh, '<', $fname or die "Can't open $fname: $!";
while (<$xcol_fh>) {
    chomp;
    next if /^\s*!/;
    my ($r, $g, $b, $name) = $_ =~ /^\s*(\d+)\s+(\d+)\s+(\d+)\s+(.*)/;
    push @palette, { name => $name, r => $r, g => $g, b => $b };
}
close $xcol_fh;

while (my $l = <STDIN>) {
    chomp $l; 

    my @triple = $l =~ /^\s*(\d+)\s+(\d+)\s+(\d+)/;
    $_->{dist} = distance([ @triple ], [ @$_{qw( r g b )} ]) for (@palette);

    say "Best matches for (", join(qq(, ), @triple), ") are: ";
    my @srt = sort { $a->{dist} <=> $b->{dist} } @palette;
    for my $col (@srt[0..9]) {
        say "$col->{name} (", join(qq(, ), @$col{qw( r g b )}), "): $col->{dist}";
    }   
}

or even simpler, using Convert::Color::X11, as suggested by LeoNerd:

use warnings;
use strict;

use 5.010;
use Convert::Color::X11;
use Color::Similarity::HCL qw( distance );

my @palette = map { { name => $_, rgb => [ Convert::Color::X11->new($_)->rgb8 ] } } Convert::Color::X11->colors;                                                                                                                              

while (my $l = <STDIN>) {
    chomp $l; 

    my @triple = $l =~ /^\s*(\d+)\s+(\d+)\s+(\d+)/;
    $_->{dist} = distance([ @triple ], $_->{rgb}) for (@palette);

    say "Best matches for (", join(qq(, ), @triple), ") are: ";
    my @srt = sort { $a->{dist} <=> $b->{dist} } @palette;
    for my $col (@srt[0..9]) {
        say "$col->{name} (", join(qq(, ), @{$col->{rgb}}), "): $col->{dist}";
    }   
}

For me, rxvt best emulates Tango palette with the following options:

-color0 black -color1 red3 -color2 chartreuse4 -color3 gold3 -color4 DodgerBlue4 -color5 plum4 -color6 turquoise4 -color7 honeydew3 -color8 gray34 -color9 firebrick2 -color10 chartreuse2 -color11 khaki -color12 SkyBlue3 -color13 plum3 -color14 cyan3 -color15 gray93

About this Archive

This page is an archive of entries in the Perl category from October 2010.

Perl: November 2009 is the previous archive.

Perl: February 2011 is the next archive.

Find recent content on the main index or look in the archives to find all content.

Pages

OpenID accepted here Learn more about OpenID