将HEX转换为最接近的X11颜色编号

16
我正在寻找一种算法/方法,将给定的十六进制代码(例如#111111 R:0x11,G:0x11,B:0x11)转换为最接近的X11颜色号码(终端可以是88或256种颜色),使用Python、PHP或VIM脚本,并且我想知道是否有人知道一种方法或者可以指导我如何实现。
提前感谢。

什么是最接近的?回答这个问题,你就有了一个算法。是三维空间中的距离吗?还是您更喜欢保留比率(颜色)、振幅(亮度)等等?一旦您有了距离的度量标准,就可以简单地选择最小值。 - Karoly Horvath
@KarolyHorvath - 我不确定哪种算法可以给我更好的结果,但我会解释一下我想做什么。我正在为我的VIM编辑器创建配色方案。使用VIM的GUI版本,我可以使用十六进制颜色。现在我想将该HEX转换为X11数字,并将其设置为VIM的控制台版本。 - markfw
5个回答

15

我也遇到了同样的问题(使用现有的gvim颜色方案并填充终端颜色值)。这是我使用的脚本(尽管ColorDist函数可能会受益于更好的颜色距离度量,就像其他一些帖子中建议的那样)。

import re
import math

colors = {
    '000000':  '16', '00005f':  '17', '000087':  '18', '0000af':  '19', '0000d7':  '20',
    '0000ff':  '21', '005f00':  '22', '005f5f':  '23', '005f87':  '24', '005faf':  '25',
    '005fd7':  '26', '005fff':  '27', '008700':  '28', '00875f':  '29', '008787':  '30',
    '0087af':  '31', '0087d7':  '32', '0087ff':  '33', '00af00':  '34', '00af5f':  '35',
    '00af87':  '36', '00afaf':  '37', '00afd7':  '38', '00afff':  '39', '00d700':  '40',
    '00d75f':  '41', '00d787':  '42', '00d7af':  '43', '00d7d7':  '44', '00d7ff':  '45',
    '00ff00':  '46', '00ff5f':  '47', '00ff87':  '48', '00ffaf':  '49', '00ffd7':  '50',
    '00ffff':  '51', '5f0000':  '52', '5f005f':  '53', '5f0087':  '54', '5f00af':  '55',
    '5f00d7':  '56', '5f00ff':  '57', '5f5f00':  '58', '5f5f5f':  '59', '5f5f87':  '60',
    '5f5faf':  '61', '5f5fd7':  '62', '5f5fff':  '63', '5f8700':  '64', '5f875f':  '65',
    '5f8787':  '66', '5f87af':  '67', '5f87d7':  '68', '5f87ff':  '69', '5faf00':  '70',
    '5faf5f':  '71', '5faf87':  '72', '5fafaf':  '73', '5fafd7':  '74', '5fafff':  '75',
    '5fd700':  '76', '5fd75f':  '77', '5fd787':  '78', '5fd7af':  '79', '5fd7d7':  '80',
    '5fd7ff':  '81', '5fff00':  '82', '5fff5f':  '83', '5fff87':  '84', '5fffaf':  '85',
    '5fffd7':  '86', '5fffff':  '87', '870000':  '88', '87005f':  '89', '870087':  '90',
    '8700af':  '91', '8700d7':  '92', '8700ff':  '93', '875f00':  '94', '875f5f':  '95',
    '875f87':  '96', '875faf':  '97', '875fd7':  '98', '875fff':  '99', '878700': '100',
    '87875f': '101', '878787': '102', '8787af': '103', '8787d7': '104', '8787ff': '105',
    '87af00': '106', '87af5f': '107', '87af87': '108', '87afaf': '109', '87afd7': '110',
    '87afff': '111', '87d700': '112', '87d75f': '113', '87d787': '114', '87d7af': '115',
    '87d7d7': '116', '87d7ff': '117', '87ff00': '118', '87ff5f': '119', '87ff87': '120',
    '87ffaf': '121', '87ffd7': '122', '87ffff': '123', 'af0000': '124', 'af005f': '125',
    'af0087': '126', 'af00af': '127', 'af00d7': '128', 'af00ff': '129', 'af5f00': '130',
    'af5f5f': '131', 'af5f87': '132', 'af5faf': '133', 'af5fd7': '134', 'af5fff': '135',
    'af8700': '136', 'af875f': '137', 'af8787': '138', 'af87af': '139', 'af87d7': '140',
    'af87ff': '141', 'afaf00': '142', 'afaf5f': '143', 'afaf87': '144', 'afafaf': '145',
    'afafd7': '146', 'afafff': '147', 'afd700': '148', 'afd75f': '149', 'afd787': '150',
    'afd7af': '151', 'afd7d7': '152', 'afd7ff': '153', 'afff00': '154', 'afff5f': '155',
    'afff87': '156', 'afffaf': '157', 'afffd7': '158', 'afffff': '159', 'd70000': '160',
    'd7005f': '161', 'd70087': '162', 'd700af': '163', 'd700d7': '164', 'd700ff': '165',
    'd75f00': '166', 'd75f5f': '167', 'd75f87': '168', 'd75faf': '169', 'd75fd7': '170',
    'd75fff': '171', 'd78700': '172', 'd7875f': '173', 'd78787': '174', 'd787af': '175',
    'd787d7': '176', 'd787ff': '177', 'd7af00': '178', 'd7af5f': '179', 'd7af87': '180',
    'd7afaf': '181', 'd7afd7': '182', 'd7afff': '183', 'd7d700': '184', 'd7d75f': '185',
    'd7d787': '186', 'd7d7af': '187', 'd7d7d7': '188', 'd7d7ff': '189', 'd7ff00': '190',
    'd7ff5f': '191', 'd7ff87': '192', 'd7ffaf': '193', 'd7ffd7': '194', 'd7ffff': '195',
    'ff0000': '196', 'ff005f': '197', 'ff0087': '198', 'ff00af': '199', 'ff00d7': '200',
    'ff00ff': '201', 'ff5f00': '202', 'ff5f5f': '203', 'ff5f87': '204', 'ff5faf': '205',
    'ff5fd7': '206', 'ff5fff': '207', 'ff8700': '208', 'ff875f': '209', 'ff8787': '210',
    'ff87af': '211', 'ff87d7': '212', 'ff87ff': '213', 'ffaf00': '214', 'ffaf5f': '215',
    'ffaf87': '216', 'ffafaf': '217', 'ffafd7': '218', 'ffafff': '219', 'ffd700': '220',
    'ffd75f': '221', 'ffd787': '222', 'ffd7af': '223', 'ffd7d7': '224', 'ffd7ff': '225',
    'ffff00': '226', 'ffff5f': '227', 'ffff87': '228', 'ffffaf': '229', 'ffffd7': '230',
    'ffffff': '231', '080808': '232', '121212': '233', '1c1c1c': '234', '262626': '235',
    '303030': '236', '3a3a3a': '237', '444444': '238', '4e4e4e': '239', '585858': '240',
    '626262': '241', '6c6c6c': '242', '767676': '243', '808080': '244', '8a8a8a': '245',
    '949494': '246', '9e9e9e': '247', 'a8a8a8': '248', 'b2b2b2': '249', 'bcbcbc': '250',
    'c6c6c6': '251', 'd0d0d0': '252', 'dadada': '253', 'e4e4e4': '254', 'eeeeee': '255',
}

## Example line from a vim colorscheme file
##hi Normal          ctermfg=NONE ctermbg=NONE gui=NONE guifg=#b7af9f guibg=#202020

def Decompose(hexval):
    return float(int(hexval[0:2], 16)), float(int(hexval[2:4], 16)), float(int(hexval[4:6], 16))

def Normalize(r, g, b):
    magsqr = r*r + g*g + b*b
    if magsqr < 0.0001:
        return 0.0, 0.0, 0.0
    n = 1.0 / math.sqrt(magsqr)
    return r*n, g*n, b*n

def ColorDist(c1, c2):
    c1r, c1g, c1b = Decompose(c1)
    c2r, c2g, c2b = Decompose(c2)

    dr = c1r - c2r
    dg = c1g - c2g
    db = c1b - c2b
    return dr*dr + dg*dg + db*db

def BestMatch(hexval):
    best = None
    bestdist = 0.0
    for key in colors.keys():
        dist = ColorDist(hexval, key)
        if best is None or dist < bestdist:
            best = colors[key]
            bestdist = dist
    return best

##                  1   2             3   4        5      6
fg = re.compile(r'^(.*)(ctermfg=)NONE(.*)(guifg=#)([^ ]*)(.*)\n$')
bg = re.compile(r'^(.*)(ctermbg=)NONE(.*)(guibg=#)([^ ]*)(.*)\n$')

with open(r'input_color_scheme.vim', 'r') as f:
    with open(r'output_color_scheme.vim', 'w') as fout:
        for line in f.readlines():
            fgmatch = fg.match(line)
            if fgmatch is not None:
                line = (fgmatch.group(1) +
                        fgmatch.group(2) +
                        BestMatch(fgmatch.group(5)) + 
                        fgmatch.group(3) +
                        fgmatch.group(4) +
                        fgmatch.group(5) +
                        fgmatch.group(6)) + '\n'

            bgmatch = bg.match(line)
            if bgmatch is not None:
                line = (bgmatch.group(1) +
                        bgmatch.group(2) +
                        BestMatch(bgmatch.group(5)) + 
                        bgmatch.group(3) +
                        bgmatch.group(4) +
                        bgmatch.group(5) +
                        bgmatch.group(6) + '\n')

            ## -- print the line
            fout.write(line)

1
谢谢你提供这个脚本。你使用了颜色表来找到颜色N,是否有一种方法可以不用表格就找到它呢?我还查看了desert256.vim,发现他们将RGB转换为XYZ,然后使用16 + (x * 16) + (y * 4) + z来找到88色终端的颜色N,使用16 + (x * 36) + (y * 6) + z来找到256色终端的颜色N。我不理解他们的公式,你知道他们是怎么得出这个公式的吗?(大多数256 VIM配色方案都使用相同的公式) - markfw

12

前往Wolfram Alpha,输入您的十六进制值,例如 "#acdffa"。 转到名为“最接近的命名HTML颜色”的部分。

我知道这不是代码,但你说了“算法 / 方法”。

干杯


太好了。非常感谢。 - Eric Duminil

8

这是一个C语言实现,不过将其转换成其他语言应该很容易。本文末尾提供了JavaScript实现。需要注意的是,C语言实现使用整数算术:

// Convert RGB24 to xterm-256 8-bit value
// For simplicity, assume RGB space is perceptually uniform.
// There are 5 places where one of two outputs needs to be chosen when the
// input is the exact middle:
// - The r/g/b channels and the gray value: the higher value output is chosen.
// - If the gray and color have same distance from the input - color is chosen.
static int rgb_to_x256(uint8_t r, uint8_t g, uint8_t b)
{
    // Calculate the nearest 0-based color index at 16 .. 231
#   define v2ci(v) (v < 48 ? 0 : v < 115 ? 1 : (v - 35) / 40)
    int ir = v2ci(r), ig = v2ci(g), ib = v2ci(b);   // 0..5 each
#   define color_index() (36 * ir + 6 * ig + ib)  /* 0..215, lazy evaluation */

    // Calculate the nearest 0-based gray index at 232 .. 255
    int average = (r + g + b) / 3;
    int gray_index = average > 238 ? 23 : (average - 3) / 10;  // 0..23

    // Calculate the represented colors back from the index
    static const int i2cv[6] = {0, 0x5f, 0x87, 0xaf, 0xd7, 0xff};
    int cr = i2cv[ir], cg = i2cv[ig], cb = i2cv[ib];  // r/g/b, 0..255 each
    int gv = 8 + 10 * gray_index;  // same value for r/g/b, 0..255

    // Return the one which is nearer to the original input rgb value
#   define dist_square(A,B,C, a,b,c) ((A-a)*(A-a) + (B-b)*(B-b) + (C-c)*(C-c))
    int color_err = dist_square(cr, cg, cb, r, g, b);
    int gray_err  = dist_square(gv, gv, gv, r, g, b);
    return color_err <= gray_err ? 16 + color_index() : 232 + gray_index;
}

这是目前由tmuxmpv使用的相同实现。您可以在tmux的github pull request中找到该算法的一些解释。

JavaScript implementation

// Convert RGB24 to xterm-256 8-bit value
// For simplicity, assume RGB space is perceptually uniform.
// There are 5 places where one of two outputs needs to be chosen when the
// input is the exact middle:
// - The r/g/b channels and the gray value: the higher value output is chosen.
// - If the gray and color have same distance from the input - color is chosen.
function RgbToX256(r, g, b) {
  // Calculate the nearest 0-based color index at 16 .. 231
  const v2ci = (v) => {
    if (v < 48) {
      return 0;
    } else if (v < 115) {
      return 1;
    } else {
      return Math.trunc((v - 35) / 40);
    }
  };

  const ir = v2ci(r);
  const ig = v2ci(g);
  const ib = v2ci(b);
  const colorIndex = (36 * ir + 6 * ig + ib);

  // Calculate the nearest 0-based gray index at 232 .. 255
  const average = Math.trunc((r + g + b) / 3);
  const grayIndex = average > 238 ? 23 : Math.trunc((average - 3) / 10);

  // Calculate the represented colors back from the index
  const i2cv = [0, 0x5F, 0x87, 0xAF, 0xD7, 0xFF];
  const cr = i2cv[ir];
  const cg = i2cv[ig];
  const cb = i2cv[ib];
  const gv = 8 + 10 * grayIndex;

  // Return the one which is nearer to the original input rgb value
  const distSquare = (A, B, C, a, b, c) => {
    return ((A - a) * (A - a) + (B - b) * (B - b) + (C - c) * (C - c));
  }
  const colorErr = distSquare(cr, cg, cb, r, g, b);
  const grayErr = distSquare(gv, gv, gv, r, g, b);

  return colorErr <= grayErr ? 16 + colorIndex : 232 + grayIndex;
}

const assertEq = (result, expect) => {
  if (result !== expect) {
    return console.log("[FAIL]", `expected: ${expect}, got ${result}`);
  }

  return console.log("[PASS]", `expected: ${expect}, got ${result}`);
}

const tests = [{
    expect: 16,
    rgb: [0, 0, 0]
  },
  {
    expect: 17,
    rgb: [0, 0, 95]
  },
  {
    expect: 18,
    rgb: [0, 0, 135]
  },
  {
    expect: 19,
    rgb: [0, 0, 175]
  },
  {
    expect: 20,
    rgb: [0, 0, 215]
  },
  {
    expect: 21,
    rgb: [0, 0, 255]
  },
  {
    expect: 22,
    rgb: [0, 95, 0]
  },
  {
    expect: 23,
    rgb: [0, 95, 95]
  },
  {
    expect: 24,
    rgb: [0, 95, 135]
  },
  {
    expect: 25,
    rgb: [0, 95, 175]
  },
  {
    expect: 26,
    rgb: [0, 95, 215]
  },
  {
    expect: 27,
    rgb: [0, 95, 255]
  },
  {
    expect: 28,
    rgb: [0, 135, 0]
  },
  {
    expect: 29,
    rgb: [0, 135, 95]
  },
  {
    expect: 30,
    rgb: [0, 135, 135]
  },
  {
    expect: 31,
    rgb: [0, 135, 175]
  },
  {
    expect: 32,
    rgb: [0, 135, 215]
  },
  {
    expect: 33,
    rgb: [0, 135, 255]
  },
  {
    expect: 34,
    rgb: [0, 175, 0]
  },
  {
    expect: 35,
    rgb: [0, 175, 95]
  },
  {
    expect: 36,
    rgb: [0, 175, 135]
  },
  {
    expect: 37,
    rgb: [0, 175, 175]
  },
  {
    expect: 38,
    rgb: [0, 175, 215]
  },
  {
    expect: 39,
    rgb: [0, 175, 255]
  },
  {
    expect: 40,
    rgb: [0, 215, 0]
  },
  {
    expect: 41,
    rgb: [0, 215, 95]
  },
  {
    expect: 42,
    rgb: [0, 215, 135]
  },
  {
    expect: 43,
    rgb: [0, 215, 175]
  },
  {
    expect: 44,
    rgb: [0, 215, 215]
  },
  {
    expect: 45,
    rgb: [0, 215, 255]
  },
  {
    expect: 46,
    rgb: [0, 255, 0]
  },
  {
    expect: 47,
    rgb: [0, 255, 95]
  },
  {
    expect: 48,
    rgb: [0, 255, 135]
  },
  {
    expect: 49,
    rgb: [0, 255, 175]
  },
  {
    expect: 50,
    rgb: [0, 255, 215]
  },
  {
    expect: 51,
    rgb: [0, 255, 255]
  },
  {
    expect: 52,
    rgb: [95, 0, 0]
  },
  {
    expect: 53,
    rgb: [95, 0, 95]
  },
  {
    expect: 54,
    rgb: [95, 0, 135]
  },
  {
    expect: 55,
    rgb: [95, 0, 175]
  },
  {
    expect: 56,
    rgb: [95, 0, 215]
  },
  {
    expect: 57,
    rgb: [95, 0, 255]
  },
  {
    expect: 58,
    rgb: [95, 95, 0]
  },
  {
    expect: 59,
    rgb: [95, 95, 95]
  },
  {
    expect: 60,
    rgb: [95, 95, 135]
  },
  {
    expect: 61,
    rgb: [95, 95, 175]
  },
  {
    expect: 62,
    rgb: [95, 95, 215]
  },
  {
    expect: 63,
    rgb: [95, 95, 255]
  },
  {
    expect: 64,
    rgb: [95, 135, 0]
  },
  {
    expect: 65,
    rgb: [95, 135, 95]
  },
  {
    expect: 66,
    rgb: [95, 135, 135]
  },
  {
    expect: 67,
    rgb: [95, 135, 175]
  },
  {
    expect: 68,
    rgb: [95, 135, 215]
  },
  {
    expect: 69,
    rgb: [95, 135, 255]
  },
  {
    expect: 70,
    rgb: [95, 175, 0]
  },
  {
    expect: 71,
    rgb: [95, 175, 95]
  },
  {
    expect: 72,
    rgb: [95, 175, 135]
  },
  {
    expect: 73,
    rgb: [95, 175, 175]
  },
  {
    expect: 74,
    rgb: [95, 175, 215]
  },
  {
    expect: 75,
    rgb: [95, 175, 255]
  },
  {
    expect: 76,
    rgb: [95, 215, 0]
  },
  {
    expect: 77,
    rgb: [95, 215, 95]
  },
  {
    expect: 78,
    rgb: [95, 215, 135]
  },
  {
    expect: 79,
    rgb: [95, 215, 175]
  },
  {
    expect: 80,
    rgb: [95, 215, 215]
  },
  {
    expect: 81,
    rgb: [95, 215, 255]
  },
  {
    expect: 82,
    rgb: [95, 255, 0]
  },
  {
    expect: 83,
    rgb: [95, 255, 95]
  },
  {
    expect: 84,
    rgb: [95, 255, 135]
  },
  {
    expect: 85,
    rgb: [95, 255, 175]
  },
  {
    expect: 86,
    rgb: [95, 255, 215]
  },
  {
    expect: 87,
    rgb: [95, 255, 255]
  },
  {
    expect: 88,
    rgb: [135, 0, 0]
  },
  {
    expect: 89,
    rgb: [135, 0, 95]
  },
  {
    expect: 90,
    rgb: [135, 0, 135]
  },
  {
    expect: 91,
    rgb: [135, 0, 175]
  },
  {
    expect: 92,
    rgb: [135, 0, 215]
  },
  {
    expect: 93,
    rgb: [135, 0, 255]
  },
  {
    expect: 94,
    rgb: [135, 95, 0]
  },
  {
    expect: 95,
    rgb: [135, 95, 95]
  },
  {
    expect: 96,
    rgb: [135, 95, 135]
  },
  {
    expect: 97,
    rgb: [135, 95, 175]
  },
  {
    expect: 98,
    rgb: [135, 95, 215]
  },
  {
    expect: 99,
    rgb: [135, 95, 255]
  },
  {
    expect: 100,
    rgb: [135, 135, 0]
  },
  {
    expect: 101,
    rgb: [135, 135, 95]
  },
  {
    expect: 102,
    rgb: [135, 135, 135]
  },
  {
    expect: 103,
    rgb: [135, 135, 175]
  },
  {
    expect: 104,
    rgb: [135, 135, 215]
  },
  {
    expect: 105,
    rgb: [135, 135, 255]
  },
  {
    expect: 106,
    rgb: [135, 175, 0]
  },
  {
    expect: 107,
    rgb: [135, 175, 95]
  },
  {
    expect: 108,
    rgb: [135, 175, 135]
  },
  {
    expect: 109,
    rgb: [135, 175, 175]
  },
  {
    expect: 110,
    rgb: [135, 175, 215]
  },
  {
    expect: 111,
    rgb: [135, 175, 255]
  },
  {
    expect: 112,
    rgb: [135, 215, 0]
  },
  {
    expect: 113,
    rgb: [135, 215, 95]
  },
  {
    expect: 114,
    rgb: [135, 215, 135]
  },
  {
    expect: 115,
    rgb: [135, 215, 175]
  },
  {
    expect: 116,
    rgb: [135, 215, 215]
  },
  {
    expect: 117,
    rgb: [135, 215, 255]
  },
  {
    expect: 118,
    rgb: [135, 255, 0]
  },
  {
    expect: 119,
    rgb: [135, 255, 95]
  },
  {
    expect: 120,
    rgb: [135, 255, 135]
  },
  {
    expect: 121,
    rgb: [135, 255, 175]
  },
  {
    expect: 122,
    rgb: [135, 255, 215]
  },
  {
    expect: 123,
    rgb: [135, 255, 255]
  },
  {
    expect: 124,
    rgb: [175, 0, 0]
  },
  {
    expect: 125,
    rgb: [175, 0, 95]
  },
  {
    expect: 126,
    rgb: [175, 0, 135]
  },
  {
    expect: 127,
    rgb: [175, 0, 175]
  },
  {
    expect: 128,
    rgb: [175, 0, 215]
  },
  {
    expect: 129,
    rgb: [175, 0, 255]
  },
  {
    expect: 130,
    rgb: [175, 95, 0]
  },
  {
    expect: 131,
    rgb: [175, 95, 95]
  },
  {
    expect: 132,
    rgb: [175, 95, 135]
  },
  {
    expect: 133,
    rgb: [175, 95, 175]
  },
  {
    expect: 134,
    rgb: [175, 95, 215]
  },
  {
    expect: 135,
    rgb: [175, 95, 255]
  },
  {
    expect: 136,
    rgb: [175, 135, 0]
  },
  {
    expect: 137,
    rgb: [175, 135, 95]
  },
  {
    expect: 138,
    rgb: [175, 135, 135]
  },
  {
    expect: 139,
    rgb: [175, 135, 175]
  },
  {
    expect: 140,
    rgb: [175, 135, 215]
  },
  {
    expect: 141,
    rgb: [175, 135, 255]
  },
  {
    expect: 142,
    rgb: [175, 175, 0]
  },
  {
    expect: 143,
    rgb: [175, 175, 95]
  },
  {
    expect: 144,
    rgb: [175, 175, 135]
  },
  {
    expect: 145,
    rgb: [175, 175, 175]
  },
  {
    expect: 146,
    rgb: [175, 175, 215]
  },
  {
    expect: 147,
    rgb: [175, 175, 255]
  },
  {
    expect: 148,
    rgb: [175, 215, 0]
  },
  {
    expect: 149,
    rgb: [175, 215, 95]
  },
  {
    expect: 150,
    rgb: [175, 215, 135]
  },
  {
    expect: 151,
    rgb: [175, 215, 175]
  },
  {
    expect: 152,
    rgb: [175, 215, 215]
  },
  {
    expect: 153,
    rgb: [175, 215, 255]
  },
  {
    expect: 154,
    rgb: [175, 255, 0]
  },
  {
    expect: 155,
    rgb: [175, 255, 95]
  },
  {
    expect: 156,
    rgb: [175, 255, 135]
  },
  {
    expect: 157,
    rgb: [175, 255, 175]
  },
  {
    expect: 158,
    rgb: [175, 255, 215]
  },
  {
    expect: 159,
    rgb: [175, 255, 255]
  },
  {
    expect: 160,
    rgb: [215, 0, 0]
  },
  {
    expect: 161,
    rgb: [215, 0, 95]
  },
  {
    expect: 162,
    rgb: [215, 0, 135]
  },
  {
    expect: 163,
    rgb: [215, 0, 175]
  },
  {
    expect: 164,
    rgb: [215, 0, 215]
  },
  {
    expect: 165,
    rgb: [215, 0, 255]
  },
  {
    expect: 166,
    rgb: [215, 95, 0]
  },
  {
    expect: 167,
    rgb: [215, 95, 95]
  },
  {
    expect: 168,
    rgb: [215, 95, 135]
  },
  {
    expect: 169,
    rgb: [215, 95, 175]
  },
  {
    expect: 170,
    rgb: [215, 95, 215]
  },
  {
    expect: 171,
    rgb: [215, 95, 255]
  },
  {
    expect: 172,
    rgb: [215, 135, 0]
  },
  {
    expect: 173,
    rgb: [215, 135, 95]
  },
  {
    expect: 174,
    rgb: [215, 135, 135]
  },
  {
    expect: 175,
    rgb: [215, 135, 175]
  },
  {
    expect: 176,
    rgb: [215, 135, 215]
  },
  {
    expect: 177,
    rgb: [215, 135, 255]
  },
  {
    expect: 178,
    rgb: [215, 175, 0]
  },
  {
    expect: 179,
    rgb: [215, 175, 95]
  },
  {
    expect: 180,
    rgb: [215, 175, 135]
  },
  {
    expect: 181,
    rgb: [215, 175, 175]
  },
  {
    expect: 182,
    rgb: [215, 175, 215]
  },
  {
    expect: 183,
    rgb: [215, 175, 255]
  },
  {
    expect: 184,
    rgb: [215, 215, 0]
  },
  {
    expect: 185,
    rgb: [215, 215, 95]
  },
  {
    expect: 186,
    rgb: [215, 215, 135]
  },
  {
    expect: 187,
    rgb: [215, 215, 175]
  },
  {
    expect: 188,
    rgb: [215, 215, 215]
  },
  {
    expect: 189,
    rgb: [215, 215, 255]
  },
  {
    expect: 190,
    rgb: [215, 255, 0]
  },
  {
    expect: 191,
    rgb: [215, 255, 95]
  },
  {
    expect: 192,
    rgb: [215, 255, 135]
  },
  {
    expect: 193,
    rgb: [215, 255, 175]
  },
  {
    expect: 194,
    rgb: [215, 255, 215]
  },
  {
    expect: 195,
    rgb: [215, 255, 255]
  },
  {
    expect: 196,
    rgb: [255, 0, 0]
  },
  {
    expect: 197,
    rgb: [255, 0, 95]
  },
  {
    expect: 198,
    rgb: [255, 0, 135]
  },
  {
    expect: 199,
    rgb: [255, 0, 175]
  },
  {
    expect: 200,
    rgb: [255, 0, 215]
  },
  {
    expect: 201,
    rgb: [255, 0, 255]
  },
  {
    expect: 202,
    rgb: [255, 95, 0]
  },
  {
    expect: 203,
    rgb: [255, 95, 95]
  },
  {
    expect: 204,
    rgb: [255, 95, 135]
  },
  {
    expect: 205,
    rgb: [255, 95, 175]
  },
  {
    expect: 206,
    rgb: [255, 95, 215]
  },
  {
    expect: 207,
    rgb: [255, 95, 255]
  },
  {
    expect: 208,
    rgb: [255, 135, 0]
  },
  {
    expect: 209,
    rgb: [255, 135, 95]
  },
  {
    expect: 210,
    rgb: [255, 135, 135]
  },
  {
    expect: 211,
    rgb: [255, 135, 175]
  },
  {
    expect: 212,
    rgb: [255, 135, 215]
  },
  {
    expect: 213,
    rgb: [255, 135, 255]
  },
  {
    expect: 214,
    rgb: [255, 175, 0]
  },
  {
    expect: 215,
    rgb: [255, 175, 95]
  },
  {
    expect: 216,
    rgb: [255, 175, 135]
  },
  {
    expect: 217,
    rgb: [255, 175, 175]
  },
  {
    expect: 218,
    rgb: [255, 175, 215]
  },
  {
    expect: 219,
    rgb: [255, 175, 255]
  },
  {
    expect: 220,
    rgb: [255, 215, 0]
  },
  {
    expect: 221,
    rgb: [255, 215, 95]
  },
  {
    expect: 222,
    rgb: [255, 215, 135]
  },
  {
    expect: 223,
    rgb: [255, 215, 175]
  },
  {
    expect: 224,
    rgb: [255, 215, 215]
  },
  {
    expect: 225,
    rgb: [255, 215, 255]
  },
  {
    expect: 226,
    rgb: [255, 255, 0]
  },
  {
    expect: 227,
    rgb: [255, 255, 95]
  },
  {
    expect: 228,
    rgb: [255, 255, 135]
  },
  {
    expect: 229,
    rgb: [255, 255, 175]
  },
  {
    expect: 230,
    rgb: [255, 255, 215]
  },
  {
    expect: 231,
    rgb: [255, 255, 255]
  },
  {
    expect: 232,
    rgb: [8, 8, 8]
  },
  {
    expect: 233,
    rgb: [18, 18, 18]
  },
  {
    expect: 234,
    rgb: [28, 28, 28]
  },
  {
    expect: 235,
    rgb: [38, 38, 38]
  },
  {
    expect: 236,
    rgb: [48, 48, 48]
  },
  {
    expect: 237,
    rgb: [58, 58, 58]
  },
  {
    expect: 238,
    rgb: [68, 68, 68]
  },
  {
    expect: 239,
    rgb: [78, 78, 78]
  },
  {
    expect: 240,
    rgb: [88, 88, 88]
  },
  {
    expect: 241,
    rgb: [98, 98, 98]
  },
  {
    expect: 242,
    rgb: [108, 108, 108]
  },
  {
    expect: 243,
    rgb: [118, 118, 118]
  },
  {
    expect: 244,
    rgb: [128, 128, 128]
  },
  {
    expect: 245,
    rgb: [138, 138, 138]
  },
  {
    expect: 246,
    rgb: [148, 148, 148]
  },
  {
    expect: 247,
    rgb: [158, 158, 158]
  },
  {
    expect: 248,
    rgb: [168, 168, 168]
  },
  {
    expect: 249,
    rgb: [178, 178, 178]
  },
  {
    expect: 250,
    rgb: [188, 188, 188]
  },
  {
    expect: 251,
    rgb: [198, 198, 198]
  },
  {
    expect: 252,
    rgb: [208, 208, 208]
  },
  {
    expect: 253,
    rgb: [218, 218, 218]
  },
  {
    expect: 254,
    rgb: [228, 228, 228]
  },
  {
    expect: 255,
    rgb: [238, 238, 238]
  }
];


for (const {
    expect,
    rgb: [r, g, b]
  } of tests) {
  assertEq(expect, RgbToX256(r, g, b));
}


4

以下是Python实现,它是常数时间的:

N = []
for i, n in enumerate([47, 68, 40, 40, 40, 21]):
    N.extend([i]*n)

def rgb_to_xterm(r, g, b):
    mx = max(r, g, b)    
    mn = min(r, g, b)

    if (mx-mn)*(mx+mn) <= 6250:
        c = 24 - (252 - ((r+g+b) // 3)) // 10
        if 0 <= c <= 23:
            return 232 + c

    return 16 + 36*N[r] + 6*N[g] + N[b]

请问您能否解释一下这段代码吗?谢谢。 - Unmanned Player
从十六进制字符串直接转换:h = "8700ff"; print(rgb_to_xterm(*(int(n, 16) for n in (h[:2], h[2:4], h[4:])))) # 93 - Doot

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接