通常端末で使える 256色
コマンドラインインターフェースで使用する今どきの大抵の文字端末では、ANSI標準の 256色が出力出来るのが普通です。
各色に決められた番号が付いていて、その番号を含めたエスケープシーケンスを出力すると、バックグラウンドカラー、フォアグラウンドカラーを変更することが出来るようになっているわけです。
#!/usr/local/bin/perl
use strict;
use warnings;
my $fg = "\x1b[38;5;";
my $bg = "\x1b[48;5;";
my $rs = "\x1b[0m";
my $color = 0;
for (my $row = 0; $row < 32; ++$row) {
for (my $col = 0; $col < 8; ++$col) {
print get_color($color);
$color++;
}
print "\n";
}
sub get_color {
my ($color) = @_;
my $number = sprintf '%3d', $color;
return qq/${bg}${color}m ${number} ${rs} ${fg}${color}m${number}${rs} /;
}
こんな風な短いスクリプトを実行すると、
画面上で各番号にひもづいた色はどんな色か確認することが出来ます。
(1行目の perl のパスはそれぞれの環境に合わせてください。)
色の並びを少し整理すると
このうち、番号0から15までは虹の色の代表色8色が明るさ違いで2パターン、また232から255までは明るさを少しづつ変更したグレースケールです。それで、残りの16から231までは、RGBの明るさを少しづつ変更した 6x6x6=216色が確保されています。
それが分かりやすいようにちょっと並べ替えると、下記のようになります。
真ん中の216色の並び方ですが、明るさの度合いを最小値を"0"として最大値を"1"とすると、RGBの3つの要素それぞれの明るさが、0.0 / 0.2 / 0.4 / 0.6 / 0.8 / 1.0 の6段階選択されており、番号の若い順から、G、B、R の順に変化させた組み合わせとなっています。
No. -R--- -B--- -G---
16 0.000 0.000 0.000
17 0.000 0.000 0.200
18 0.000 0.000 0.400
19 0.000 0.000 0.600
20 0.000 0.000 0.800
21 0.000 0.000 1.000
22 0.000 0.200 0.000
23 0.000 0.200 0.200
24 0.000 0.200 0.400
25 0.000 0.200 0.600
26 0.000 0.200 0.800
27 0.000 0.200 1.000
28 0.000 0.400 0.000
29 0.000 0.400 0.200
30 0.000 0.400 0.400
31 0.000 0.400 0.600
32 0.000 0.400 0.800
33 0.000 0.400 1.000
34 0.000 0.600 0.000
35 0.000 0.600 0.200
36 0.000 0.600 0.400
:
(この間は省略)
:
220 1.000 0.800 0.000
221 1.000 0.800 0.200
222 1.000 0.800 0.400
223 1.000 0.800 0.600
224 1.000 0.800 0.800
225 1.000 0.800 1.000
226 1.000 1.000 0.000
227 1.000 1.000 0.200
228 1.000 1.000 0.400
229 1.000 1.000 0.600
230 1.000 1.000 0.800
231 1.000 1.000 1.000
それで、上のチャートのような番号順の色見本を示して、この中から好きな色が選べるよ…って説明している記事は、あちこちでよく見かけます。
しかしこのチャートは、ヒトが目的の色を探すのに適切な順番には並んでいません。ヒトは、虹の色の並び、明るさ、鮮やかさ、で並べないと目的の色をうまく選べないのです。
HSV色空間
RGBとは別にHSV色空間というものがあります。Hは色相(Hue)、Sは彩度(Saturation)、Vは明度(Value)の頭文字で、美術分野で教える色立体などはこの3つのパラメータの順に色を並べています。というわけで上のRGBの値の順に番号を振られている216色を並べ替えます。
RGBからHSVへの変換は機械的に行うことが出来ますが、その方法はちょっとややこしいのでWikipediaのこちらの説明をご覧ください。
No. -R--- -B--- -G--- -H--- -S--- -V---
16 0.000 0.000 0.000 0.000 0.000 0.000
17 0.000 0.000 0.200 0.333 1.000 0.200
18 0.000 0.000 0.400 0.333 1.000 0.400
19 0.000 0.000 0.600 0.333 1.000 0.600
20 0.000 0.000 0.800 0.333 1.000 0.800
21 0.000 0.000 1.000 0.333 1.000 1.000
22 0.000 0.200 0.000 0.667 1.000 0.200
23 0.000 0.200 0.200 0.500 1.000 0.200
24 0.000 0.200 0.400 0.417 1.000 0.400
25 0.000 0.200 0.600 0.389 1.000 0.600
26 0.000 0.200 0.800 0.375 1.000 0.800
27 0.000 0.200 1.000 0.367 1.000 1.000
28 0.000 0.400 0.000 0.667 1.000 0.400
29 0.000 0.400 0.200 0.583 1.000 0.400
30 0.000 0.400 0.400 0.500 1.000 0.400
31 0.000 0.400 0.600 0.444 1.000 0.600
32 0.000 0.400 0.800 0.417 1.000 0.800
33 0.000 0.400 1.000 0.400 1.000 1.000
34 0.000 0.600 0.000 0.667 1.000 0.600
35 0.000 0.600 0.200 0.611 1.000 0.600
36 0.000 0.600 0.400 0.556 1.000 0.600
:
(この間は省略)
:
220 1.000 0.800 0.000 0.867 1.000 1.000
221 1.000 0.800 0.200 0.875 0.800 1.000
222 1.000 0.800 0.400 0.889 0.600 1.000
223 1.000 0.800 0.600 0.917 0.400 1.000
224 1.000 0.800 0.800 0.000 0.200 1.000
225 1.000 0.800 1.000 0.167 0.200 1.000
226 1.000 1.000 0.000 0.833 1.000 1.000
227 1.000 1.000 0.200 0.833 0.800 1.000
228 1.000 1.000 0.400 0.833 0.600 1.000
229 1.000 1.000 0.600 0.833 0.400 1.000
230 1.000 1.000 0.800 0.833 0.200 1.000
231 1.000 1.000 1.000 0.000 0.000 1.000
算出されたHSVで色を並べ替える
算出されたHSVのパラメータを調べてみると、明度は、0.2 が7色、0.4 が19色、0.6 が37色、0.8 が61色、1.0 が92色でした。明るい色ほど色数が多くなっています。
また彩度は、0.0 から 1.0 までの11段階、色相は、0.0 から 0.967 まで60段階でした。
軸が3つあるので全てを活かして平面に並べることはできないのですが、少し試行錯誤して次のように並べると分かりやすくなることが分かりました。
- 明度については上に暗い色、下に進むにつれて明るい色を並べる
- 彩度については左にグレー、右に進むにつれて鮮やかな色を並べる
- 色相については、同じ明度/彩度の範囲内で縦に順番に並べる
というわけで、これら216色に、No.0-15の代表色、No.232-255のグレーも合わせて並べ替えた結果が下記です。
これで、「明るめだけどちょっとくすんだ緑」とか「あざやかだけど暗い紫」などのように人間の感覚で色を探すことが出来るようになりました。
この色見本を出力するスクリプト
この色見本をテキストで出力する perl スクリプトをつけておきます。
1行目のperlのパスは環境に合わせて修正してください。
スクリプトの出力を lessにかける場合は、colorsample.pl | less -R のように -R オプションを付けてください。
#!/usr/local/bin/perl
use strict;
use warnings;
my $fg = "\x1b[38;5;";
my $bg = "\x1b[48;5;";
my $rs = "\x1b[0m";
my $color = 0;
#print " -1\n";
p( 0,1,40);p( 8,1,40);cr();
p( 1,1,40);p( 9,1,40);cr();
p( 5,1,40);p( 13,1,40);cr();
p( 4,1,40);p( 12,1,40);cr();
p( 6,1,40);p( 14,1,40);cr();
p( 2,1,40);p( 10,1,40);cr();
p( 3,1,40);p( 11,1,40);cr();
p( 7,1,40);p( 15,1,40);cr();
#cr();
p(232,1,26);p( 240,1,27);p(248,1,27);cr();
p(233,1,26);p( 241,1,27);p(249,1,27);cr();
p(234,1,26);p( 242,1,27);p(250,1,27);cr();
p(235,1,26);p( 243,1,27);p(251,1,27);cr();
p(236,1,26);p( 244,1,27);p(252,1,27);cr();
p(237,1,26);p( 245,1,27);p(253,1,27);cr();
p(238,1,26);p( 246,1,27);p(254,1,27);cr();
p(239,1,26);p( 247,1,27);p(255,1,27);cr();
#cr();
p( 59,1,40);p( 52,1,40);cr();
p( 59,0,40);p( 53,1,40);cr();
p( 59,0,40);p( 17,1,40);cr();
p( 59,0,40);p( 23,1,40);cr();
p( 59,0,40);p( 22,1,40);cr();
p( 59,0,40);p( 58,1,40);cr();
p(102,1,26);p( 95,1,27);p( 88,1,27);cr();
p(102,0,26);p( 95,0,27);p( 89,1,27);cr();
p(102,0,26);p( 96,1,27);p( 90,1,27);cr();
p(102,0,26);p( 96,0,27);p( 54,1,27);cr();
p(102,0,26);p( 60,1,27);p( 18,1,27);cr();
p(102,0,26);p( 60,0,27);p( 24,1,27);cr();
p(102,0,26);p( 66,1,27);p( 30,1,27);cr();
p(102,0,26);p( 66,0,27);p( 29,1,27);cr();
p(102,0,26);p( 65,1,27);p( 28,1,27);cr();
p(102,0,26);p( 65,0,27);p( 64,1,27);cr();
p(102,0,26);p(101,1,27);p(100,1,27);cr();
p(102,0,26);p(101,0,27);p( 94,1,27);cr();
p(145,1,20);p(138,1,20);p(131,1,20);p(124,1,20);cr();
p(145,0,20);p(138,0,20);p(131,0,20);p(125,1,20);cr();
p(145,0,20);p(138,0,20);p(132,1,20);p(126,1,20);cr();
p(145,0,20);p(139,1,20);p(133,1,20);p(127,1,20);cr();
p(145,0,20);p(139,0,20);p(133,0,20);p( 91,1,20);cr();
p(145,0,20);p(139,0,20);p( 97,1,20);p( 55,1,20);cr();
p(145,0,20);p(103,1,20);p( 61,1,20);p( 19,1,20);cr();
p(145,0,20);p(103,0,20);p( 61,0,20);p( 25,1,20);cr();
p(145,0,20);p(103,0,20);p( 67,1,20);p( 31,1,20);cr();
p(145,0,20);p(109,1,20);p( 73,1,20);p( 37,1,20);cr();
p(145,0,20);p(109,0,20);p( 73,0,20);p( 36,1,20);cr();
p(145,0,20);p(109,0,20);p( 72,1,20);p( 35,1,20);cr();
p(145,0,20);p(108,1,20);p( 71,1,20);p( 34,1,20);cr();
p(145,0,20);p(108,0,20);p( 71,0,20);p( 70,1,20);cr();
p(145,0,20);p(108,0,20);p(107,1,20);p(106,1,20);cr();
p(145,0,20);p(144,1,20);p(143,1,20);p(142,1,20);cr();
p(145,0,20);p(144,0,20);p(143,0,20);p(136,1,20);cr();
p(145,0,20);p(144,0,20);p(137,1,20);p(130,1,20);cr();
p(188,1,16);p(181,1,16);p(174,1,16);p(167,1,16);p(160,1,16);cr();
p(188,0,16);p(181,0,16);p(174,0,16);p(168,1,16);p(161,1,16);cr();
p(188,0,16);p(181,0,16);p(175,1,16);p(168,0,16);p(162,1,16);cr();
p(188,0,16);p(181,0,16);p(175,0,16);p(169,1,16);p(163,1,16);cr();
p(188,0,16);p(182,1,16);p(176,1,16);p(170,1,16);p(164,1,16);cr();
p(188,0,16);p(182,0,16);p(176,0,16);p(134,1,16);p(128,1,16);cr();
p(188,0,16);p(182,0,16);p(140,1,16);p(134,0,16);p( 92,1,16);cr();
p(188,0,16);p(182,0,16);p(140,0,16);p( 98,1,16);p( 56,1,16);cr();
p(188,0,16);p(146,1,16);p(104,1,16);p( 62,1,16);p( 20,1,16);cr();
p(188,0,16);p(146,0,16);p(104,0,16);p( 68,1,16);p( 26,1,16);cr();
p(188,0,16);p(146,0,16);p(110,1,16);p( 68,0,16);p( 32,1,16);cr();
p(188,0,16);p(146,0,16);p(110,0,16);p( 74,1,16);p( 38,1,16);cr();
p(188,0,16);p(152,1,16);p(116,1,16);p( 80,1,16);p( 44,1,16);cr();
p(188,0,16);p(152,0,16);p(116,0,16);p( 79,1,16);p( 43,1,16);cr();
p(188,0,16);p(152,0,16);p(115,1,16);p( 79,0,16);p( 42,1,16);cr();
p(188,0,16);p(152,0,16);p(115,0,16);p( 78,1,16);p( 41,1,16);cr();
p(188,0,16);p(151,1,16);p(114,1,16);p( 77,1,16);p( 40,1,16);cr();
p(188,0,16);p(151,0,16);p(114,0,16);p(113,1,16);p( 76,1,16);cr();
p(188,0,16);p(151,0,16);p(150,1,16);p(113,0,16);p(112,1,16);cr();
p(188,0,16);p(151,0,16);p(150,0,16);p(149,1,16);p(148,1,16);cr();
p(188,0,16);p(187,1,16);p(186,1,16);p(185,1,16);p(184,1,16);cr();
p(188,0,16);p(187,0,16);p(186,0,16);p(179,1,16);p(178,1,16);cr();
p(188,0,16);p(187,0,16);p(180,1,16);p(179,0,16);p(172,1,16);cr();
p(188,0,16);p(187,0,16);p(180,0,16);p(173,1,16);p(166,1,16);cr();
p(231,1,13);p(224,1,13);p(217,1,13);p(210,1,13);p(203,1,14);p(196,1,14);cr();
p(231,0,13);p(224,0,13);p(217,0,13);p(210,0,13);p(204,1,14);p(197,1,14);cr();
p(231,0,13);p(224,0,13);p(217,0,13);p(211,1,13);p(204,0,14);p(198,1,14);cr();
p(231,0,13);p(224,0,13);p(218,1,13);p(211,0,13);p(205,1,14);p(198,0,14);cr();
p(231,0,13);p(224,0,13);p(218,0,13);p(212,1,13);p(206,1,14);p(199,1,14);cr();
p(231,0,13);p(224,0,13);p(218,0,13);p(212,0,13);p(206,0,14);p(200,1,14);cr();
p(231,0,13);p(225,1,13);p(219,1,13);p(213,1,13);p(207,1,14);p(201,1,14);cr();
p(231,0,13);p(225,0,13);p(219,0,13);p(213,0,13);p(171,1,14);p(165,1,14);cr();
p(231,0,13);p(225,0,13);p(219,0,13);p(177,1,13);p(171,0,14);p(129,1,14);cr();
p(231,0,13);p(225,0,13);p(183,1,13);p(177,0,13);p(135,1,14);p(129,0,14);cr();
p(231,0,13);p(225,0,13);p(183,0,13);p(141,1,13);p( 99,1,14);p( 93,1,14);cr();
p(231,0,13);p(225,0,13);p(183,0,13);p(141,0,13);p( 99,0,14);p( 57,1,14);cr();
p(231,0,13);p(189,1,13);p(147,1,13);p(105,1,13);p( 63,1,14);p( 21,1,14);cr();
p(231,0,13);p(189,0,13);p(147,0,13);p(105,0,13);p( 69,1,14);p( 27,1,14);cr();
p(231,0,13);p(189,0,13);p(147,0,13);p(111,1,13);p( 69,0,14);p( 33,1,14);cr();
p(231,0,13);p(189,0,13);p(153,1,13);p(111,0,13);p( 75,1,14);p( 33,0,14);cr();
p(231,0,13);p(189,0,13);p(153,0,13);p(117,1,13);p( 81,1,14);p( 39,1,14);cr();
p(231,0,13);p(189,0,13);p(153,0,13);p(117,0,13);p( 81,0,14);p( 45,1,14);cr();
p(231,0,13);p(195,1,13);p(159,1,13);p(123,1,13);p( 87,1,14);p( 51,1,14);cr();
p(231,0,13);p(195,0,13);p(159,0,13);p(123,0,13);p( 86,1,14);p( 50,1,14);cr();
p(231,0,13);p(195,0,13);p(159,0,13);p(122,1,13);p( 86,0,14);p( 49,1,14);cr();
p(231,0,13);p(195,0,13);p(158,1,13);p(122,0,13);p( 85,1,14);p( 49,0,14);cr();
p(231,0,13);p(195,0,13);p(158,0,13);p(121,1,13);p( 84,1,14);p( 48,1,14);cr();
p(231,0,13);p(195,0,13);p(158,0,13);p(121,0,13);p( 84,0,14);p( 47,1,14);cr();
p(231,0,13);p(194,1,13);p(157,1,13);p(120,1,13);p( 83,1,14);p( 46,1,14);cr();
p(231,0,13);p(194,0,13);p(157,0,13);p(120,0,13);p(119,1,14);p( 82,1,14);cr();
p(231,0,13);p(194,0,13);p(157,0,13);p(156,1,13);p(119,0,14);p(118,1,14);cr();
p(231,0,13);p(194,0,13);p(193,1,13);p(156,0,13);p(155,1,14);p(118,0,14);cr();
p(231,0,13);p(194,0,13);p(193,0,13);p(192,1,13);p(191,1,14);p(154,1,14);cr();
p(231,0,13);p(194,0,13);p(193,0,13);p(192,0,13);p(191,0,14);p(190,1,14);cr();
p(231,0,13);p(230,1,13);p(229,1,13);p(228,1,13);p(227,1,14);p(226,1,14);cr();
p(231,0,13);p(230,0,13);p(229,0,13);p(228,0,13);p(221,1,14);p(220,1,14);cr();
p(231,0,13);p(230,0,13);p(229,0,13);p(222,1,13);p(221,0,14);p(214,1,14);cr();
p(231,0,13);p(230,0,13);p(223,1,13);p(222,0,13);p(215,1,14);p(214,0,14);cr();
p(231,0,13);p(230,0,13);p(223,0,13);p(216,1,13);p(209,1,14);p(208,1,14);cr();
p(231,0,13);p(230,0,13);p(223,0,13);p(216,0,13);p(209,0,14);p(202,1,14);cr();
sub p {
my ($color,$tf,$len) = @_;
my $num = sprintf ' %3d',$color;
my $dum = " ";
my $spc = sprintf '%*s',$len-4," ";
if ($tf==1) {
print "${num}${bg}${color}m${spc}${rs}";
} else {
print "${bg}${color}m${dum}${spc}${rs}";
}
}
sub cr {
print "\n";
}
開発しているOSS
私は、OSS として vi と Vim ユーザのためのバイナリエディタを開発しているのですが、その中で色を選択する際の見本として上記のリストを取り入れています。ご興味のある方は、https://hxavi.net/ をご覧ください。


