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 from October 2010 listed from newest to oldest.

November 2009 is the previous archive.

November 2010 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