代码之家  ›  专栏  ›  技术社区  ›  moo

将十六进制颜色转换为RGB,反之亦然

  •  44
  • moo  · 技术社区  · 17 年前

    最有效的方法是什么?

    9 回复  |  直到 9 年前
        1
  •  10
  •   Vicent Marti    17 年前

    实际答案:取决于您要查找的十六进制颜色值的类型(例如565、555、888、8888等)、alpha位的数量、实际颜色分布(rgb与bgr…)以及大量其他变量。

    这里是使用C++模板(ScummVM直接)的大多数RGB值的通用算法。

    template<class T>
    uint32 RGBToColor(uint8 r, uint8 g, uint8 b) {
    return T::kAlphaMask |
           (((r << T::kRedShift) >> (8 - T::kRedBits)) & T::kRedMask) |
           (((g << T::kGreenShift) >> (8 - T::kGreenBits)) & T::kGreenMask) |
           (((b << T::kBlueShift) >> (8 - T::kBlueBits)) & T::kBlueMask);
    }
    

    下面是565的示例颜色结构(16位颜色的标准格式):

    template<>
    struct ColorMasks<565> {
    enum {
        highBits    = 0xF7DEF7DE,
        lowBits     = 0x08210821,
        qhighBits   = 0xE79CE79C,
        qlowBits    = 0x18631863,
    
    
        kBytesPerPixel = 2,
    
        kAlphaBits  = 0,
        kRedBits    = 5,
        kGreenBits  = 6,
        kBlueBits   = 5,
    
        kAlphaShift = kRedBits+kGreenBits+kBlueBits,
        kRedShift   = kGreenBits+kBlueBits,
        kGreenShift = kBlueBits,
        kBlueShift  = 0,
    
        kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift,
        kRedMask   = ((1 << kRedBits) - 1) << kRedShift,
        kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
        kBlueMask  = ((1 << kBlueBits) - 1) << kBlueShift,
    
        kRedBlueMask = kRedMask | kBlueMask
    
    };
    };
    
        2
  •  161
  •   Jeremy Cantrell    9 年前

    在蟒蛇中:

    def hex_to_rgb(value):
        """Return (red, green, blue) for the color given as #rrggbb."""
        value = value.lstrip('#')
        lv = len(value)
        return tuple(int(value[i:i + lv // 3], 16) for i in range(0, lv, lv // 3))
    
    def rgb_to_hex(red, green, blue):
        """Return color as #rrggbb for the given color values."""
        return '#%02x%02x%02x' % (red, green, blue)
    
    hex_to_rgb("#ffffff")           #==> (255, 255, 255)
    hex_to_rgb("#ffffffffffff")     #==> (65535, 65535, 65535)
    rgb_to_hex(255, 255, 255)       #==> '#ffffff'
    rgb_to_hex(65535, 65535, 65535) #==> '#ffffffffffff'
    
        3
  •  36
  •   Chris H.    11 年前

    在python中,十六进制和“rgb”之间的转换也包含在绘图包中。 matplotlib . 即

    import matplotlib.colors as colors
    

    然后

    colors.hex2color('#ffffff')        #==> (1.0, 1.0, 1.0)
    colors.rgb2hex((1.0, 1.0, 1.0))    #==> '#ffffff'
    

    警告是,颜色中的RGB值假定在0.0和1.0之间。如果你想在0到255之间转换,你需要做一个小的转换。明确地,

    def hex_to_rgb(hex_string):
        rgb = colors.hex2color(hex_string)
        return tuple([int(255*x) for x in rgb])
    
    def rgb_to_hex(rgb_tuple):
        return colors.rgb2hex([1.0*x/255 for x in rgb_tuple])
    

    另一个注意事项是 colors.hex2color 只接受有效的十六进制颜色字符串。

        4
  •  18
  •   Julien Roncaglia    14 年前

    非常快:

    int r = ( hexcolor >> 16 ) & 0xFF;
    
    int g = ( hexcolor >> 8 ) & 0xFF;
    
    int b = hexcolor & 0xFF;
    
    int hexcolor = (r << 16) + (g << 8) + b;
    
        5
  •  7
  •   Rick Westera    14 年前

    修改jeremy的python answer以处理短的css rgb值,如0、999和fff(浏览器将呈现为黑色、中灰色和白色):

    def hex_to_rgb(value):
        value = value.lstrip('#')
        lv = len(value)
        if lv == 1:
            v = int(value, 16)*17
            return v, v, v
        if lv == 3:
            return tuple(int(value[i:i+1], 16)*17 for i in range(0, 3))
        return tuple(int(value[i:i+lv/3], 16) for i in range(0, lv, lv/3))
    
        6
  •  2
  •   Julien Roncaglia    14 年前

    十六进制值只是以十六进制表示的RGB数字。所以你只需要把每对十六进制数字转换成十进制。

    例子:

    #FF6400 = RGB(0xFF, 0x64, 0x00) = RGB(255, 100, 0)
    
        7
  •  2
  •   PADYMKO    9 年前

    您只需要将十六进制值(部分)转换为十进制值,反之亦然。还需要考虑的是,十六进制值可能包含6或3个字符(不含字符“”)。

    在python 3.5上实现

    """Utils for working with colors."""
    
    import textwrap
    
    
    def rgb_to_hex(value1, value2, value3):
        """
        Convert RGB value (as three numbers each ranges from 0 to 255) to hex format.
    
        >>> rgb_to_hex(235, 244, 66)
        '#EBF442'
        >>> rgb_to_hex(56, 28, 26)
        '#381C1A'
        >>> rgb_to_hex(255, 255, 255)
        '#FFFFFF'
        >>> rgb_to_hex(0, 0, 0)
        '#000000'
        >>> rgb_to_hex(203, 244, 66)
        '#CBF442'
        >>> rgb_to_hex(53, 17, 8)
        '#351108'
        """
    
        for value in (value1, value2, value3):
            if not 0 <= value <= 255:
                raise ValueError('Value each slider must be ranges from 0 to 255')
        return '#{0:02X}{1:02X}{2:02X}'.format(value1, value2, value3)
    
    
    def hex_to_rgb(value):
        """
        Convert color`s value in hex format to RGB format.
    
        >>> hex_to_rgb('fff')
        (255, 255, 255)
        >>> hex_to_rgb('ffffff')
        (255, 255, 255)
        >>> hex_to_rgb('#EBF442')
        (235, 244, 66)
        >>> hex_to_rgb('#000000')
        (0, 0, 0)
        >>> hex_to_rgb('#000')
        (0, 0, 0)
        >>> hex_to_rgb('#54433f')
        (84, 67, 63)
        >>> hex_to_rgb('#f7efed')
        (247, 239, 237)
        >>> hex_to_rgb('#191616')
        (25, 22, 22)
        """
    
        if value[0] == '#':
            value = value[1:]
    
        len_value = len(value)
    
        if len_value not in [3, 6]:
            raise ValueError('Incorect a value hex {}'.format(value))
    
        if len_value == 3:
            value = ''.join(i * 2 for i in value)
        return tuple(int(i, 16) for i in textwrap.wrap(value, 2))
    
    
    if __name__ == '__main__':
        import doctest
        doctest.testmod()
    

    在javascript上实现(通过支持ES6适应nodejs)

    const assert = require('assert');
    
    /**
     * Return a color`s value in the hex format by passed the RGB format.
     * @param  {integer} value1 An value in ranges from 0 to 255
     * @param  {integer} value2 An value in ranges from 0 to 255
     * @param  {integer} value3 An value in ranges from 0 to 255
     * @return {string}        A color`s value in the hex format
     */
    const RGBtoHex = (value1, value2, value3) => {
        const values = [value1, value2, value3];
        let result = '#';
        for (let i = 0; i < 3; i += 1) {
            // validation input
            if (values[i] < 0 || values[i] > 255) throw new Error('An each value of RGB format must be ranges from 0 to 255');
    
            // append to result values as hex with at least width 2
            result += (('0' + values[i].toString(16)).slice(-2));
        }
        return result.toUpperCase();
    };
    
    
    /**
     * Convert a value from the hex format to RGB and return as an array
     * @param  {int} value A color`s value in the hex format
     * @return {array}     Array values of the RGB format
     */
    const hexToRGB = (value) => {
        let val = value;
    
        val = (value[0] === '#') ? value.slice(1) : value;
    
        if ([3, 6].indexOf(val.length) === -1) throw new Error(`Incorect a value of the hex format: ${value}`);
    
        if (val.length === 3) val = val.split('').map(item => item.repeat(2)).join('');
    
        return val.match(/.{2}/g).map(item => parseInt(`0x${item}`, 16));
    };
    
    assert.deepEqual(hexToRGB('fff'), [255, 255, 255]);
    assert.deepEqual(hexToRGB('#fff'), [255, 255, 255]);
    assert.deepEqual(hexToRGB('#000000'), [0, 0, 0]);
    assert.deepEqual(hexToRGB('000000'), [0, 0, 0]);
    assert.deepEqual(hexToRGB('#d7dee8'), [215, 222, 232]);
    assert.deepEqual(hexToRGB('#1E2F49'), [30, 47, 73]);
    assert.deepEqual(hexToRGB('#030914'), [3, 9, 20]);
    
    assert.equal(RGBtoHex(255, 255, 255), '#FFFFFF');
    assert.equal(RGBtoHex(0, 0, 0), '#000000');
    assert.equal(RGBtoHex(96, 102, 112), '#606670');
    assert.equal(RGBtoHex(199, 204, 214), '#C7CCD6');
    assert.equal(RGBtoHex(22, 99, 224), '#1663E0');
    assert.equal(RGBtoHex(0, 8, 20), '#000814');
    
    
    module.exports.RGBtoHex = RGBtoHex;
    module.exports.hexToRGB = hexToRGB;
    

    C的实施(针对C11标准)

    // a type for a struct of RGB color
    typedef struct _ColorRGB {
        unsigned short int red;
        unsigned short int green;
        unsigned short int blue;
    } colorRGB_t;
    
    
    /*
        Convert a color`s value from the hex format to the RGB.
        Return -1 if a passed value in the hex format is not correct, otherwise - return 0;
     */
    static int
    convertColorHexToRGB(const char originValue[], colorRGB_t *colorRGB) {
    
        // a full value of color in hex format must constains 6 charapters
        char completedValue[6];
        size_t lenOriginValue;
        size_t lenCompletedValue;
    
        // an intermediary variable for keeping value in the hex format
        char hexSingleValue[3];
    
        // a temp pointer to char, need only to the strtol()
        char *ptr;
    
        // a variable for keeping a converted number in the hex to the decimal format
        long int number;
    
        // validation input
        lenOriginValue = strlen(originValue);
        if (lenOriginValue > 7 || lenOriginValue < 3) return -1;
    
        // copy value without sign '#', if found as first in the string
        (originValue[0] == '#') ? strcpy(completedValue, originValue + 1) : strcpy(completedValue, originValue);
    
        lenCompletedValue = strlen(completedValue);
    
        // if the value has only 3 charapters, dublicate an each after itself
        // but if not full version of the hex name of a color (6 charapters), return -1
        if (lenCompletedValue == 3) {
            completedValue[5] = completedValue[2];
            completedValue[4] = completedValue[2];
            completedValue[3] = completedValue[1];
            completedValue[2] = completedValue[1];
            completedValue[1] = completedValue[0];
        } else if (lenCompletedValue != 6) return -1;
    
        // convert string, by parts, to decimal values and keep it in a struct
    
        sprintf(hexSingleValue, "%c%c", completedValue[0], completedValue[1]);
        number = strtol(hexSingleValue, &ptr, 16);
        colorRGB->red = number;
    
        sprintf(hexSingleValue, "%c%c", completedValue[2], completedValue[3]);
        number = strtol(hexSingleValue, &ptr, 16);
        colorRGB->green = number;
    
        sprintf(hexSingleValue, "%c%c", completedValue[4], completedValue[5]);
        number = strtol(hexSingleValue, &ptr, 16);
        colorRGB->blue = number;
    
        return 0;
    }
    
    
    /*
        Convert a color`s value from the RGB format to the hex
     */
    static int
    convertColorRGBToHex(const colorRGB_t *colorRGB, char value[8]) {
        sprintf(value, "#%02X%02X%02X", colorRGB->red, colorRGB->green, colorRGB->blue);
        return 0;
    }
    
    
    /*
        Forming a string representation data in an instance of the structure colorRGB_t
     */
    static int
    getRGBasString(const colorRGB_t *colorRGB, char str[18]) {
        sprintf(str, "rgb(%d, %d, %d)", colorRGB->red, colorRGB->green, colorRGB->blue);
        return 0;
    }
    
    
    int main (int argv, char **argc)
    {
        char str[18];
        char hex[8];
    
        colorRGB_t *colorRGB_;
        colorRGB_ = (colorRGB_t *)malloc(sizeof(colorRGB_));
    
        convertColorHexToRGB("fff", colorRGB_);
        getRGBasString(colorRGB_, str);
        printf("Hex 'fff' to RGB %s\n", str);
        convertColorRGBToHex(colorRGB_, hex);
        printf("RGB %s to hex '%s'\n", str, hex);
    
        convertColorHexToRGB("000000", colorRGB_);
        getRGBasString(colorRGB_, str);
        printf("Hex '000000' to RGB %s\n", str);
        convertColorRGBToHex(colorRGB_, hex);
        printf("RGB %s to hex '%s'\n", str, hex);
    
        convertColorHexToRGB("#000000", colorRGB_);
        getRGBasString(colorRGB_, str);
        printf("Hex '#000000' to RGB %s\n", str);
        convertColorRGBToHex(colorRGB_, hex);
        printf("RGB %s to hex '%s'\n", str, hex);
    
        convertColorHexToRGB("#FFF", colorRGB_);
        getRGBasString(colorRGB_, str);
        printf("Hex '#FFF' to RGB %s\n", str);
        convertColorRGBToHex(colorRGB_, hex);
        printf("RGB %s to hex '%s'\n", str, hex);
    
        free(colorRGB_);
    }
    

    编译后的结果(使用gcc)

    Hex 'fff' to RGB rgb(255, 255, 255)
    RGB rgb(255, 255, 255) to hex '#FFFFFF'
    Hex '000000' to RGB rgb(0, 0, 0)
    RGB rgb(0, 0, 0) to hex '#000000'
    Hex '#000000' to RGB rgb(0, 0, 0)
    RGB rgb(0, 0, 0) to hex '#000000'
    Hex '#FFF' to RGB rgb(255, 255, 255)
    RGB rgb(255, 255, 255) to hex '#FFFFFF'
    
        8
  •  1
  •   David Borin    14 年前
    哎呀!/usr/bin/env python
    
    进口再
    导入系统
    
    def hex_to_rgb(值):
    value=value.lstrip('')
    LV= LeN(值)
    返回tuple(int(值[i:i+lv/3],16),用于范围(0、lv、lv/3)中的i)
    
    定义rgb_到_hex(rgb):
    RGB=EVE(RGB)
    R= RGB〔0〕
    g= RGB [ 1 ]
    B= RGB〔2〕
    返回“%02x%02x%02x%”(R、G、B)
    
    DEF主体():
    color=raw_input(“hex[ffffff]或rgb[255、255、255]值(无值退出程序):”)
    而颜色:
    如果是re.search('\[A-FA-F0-9][A-FA-F0-9][A-FA-F0-9][A-FA-F0-9][A-FA-F0-9][A-FA-F0-9][A-FA-F0-9]',颜色):
    已转换=十六进制转换为RGB(颜色)
    打印转换
    elif re.search(“[0-9]1,3,[0-9]1,3,[0-9]1,3”,颜色):
    已转换=rgb_到_hex(颜色)
    打印转换
    elif color='':
    系统退出(0)
    其他:
    打印“您没有输入有效值!”
    color=raw_input(“hex[ffffff]或rgb[255、255、255]值(无值退出程序):”)
    
    如果“名称”=
    主体()
    
        9
  •  1
  •   Patricio Rossi    12 年前

    这是我在C++ 11中使用的代码的一个片段。 您可以发送十六进制值或字符串:

        void Color::SetColor(string color) {
        // try catch will be necessary if your string is not sanitized before calling this function.
             SetColor(std::stoul(color, nullptr, 16));
        }
    
        void Color::SetColor(uint32_t number) {
            B = number & 0xFF;
            number>>= 8;
            G = number & 0xFF;
            number>>= 8;
            R = number & 0xFF;
        }
    
    
    
     // ex:
     SetColor("ffffff");
     SetColor(0xFFFFFF);