【问题标题】:Converting hex color to RGB and vice-versa将十六进制颜色转换为 RGB,反之亦然
【发布时间】:2010-09-17 21:07:19
【问题描述】:

最有效的方法是什么?

【问题讨论】:

  • 您可能想要定义语言。这将对所选算法产生影响。

标签: colors hex rgb


【解决方案1】:

在python中:

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'

【讨论】:

  • 您能解释一下rbg_to_hex 的格式中发生了什么吗?
  • 函数中,rgb是一个3个int的元组。该格式字符串只是一个 # 后跟三个 %02x,它只是给出了一个用零填充的 2 位 int 十六进制值。
  • 我很久以前就发布了这个,它仍然是我最喜欢的 Python 代码块之一(我已经编写过)
  • 这是一个很棒的发现,你不介意我在我的一些 GPL 代码中使用它吗? :)
  • 对于rgb_to_hex,如果您不想将元​​组作为参数放入,您始终可以在参数列表中执行*rbg,它仍然可以正常工作(如果你没有输入三个参数)。
【解决方案2】:

在 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 只接受有效的十六进制颜色字符串。

【讨论】:

    【解决方案3】:

    真的很快:

    int r = ( hexcolor >> 16 ) & 0xFF;
    
    int g = ( hexcolor >> 8 ) & 0xFF;
    
    int b = hexcolor & 0xFF;
    
    int hexcolor = (r << 16) + (g << 8) + b;
    

    【讨论】:

    • 小心你的运算符优先级:+ 的优先级高于
    • 很好.. 答案已经存在了 1.5 年,没有人发现。
    • 嗯...如果 int 是 16 位。红色被转移到比特桶。
    • @harvey,完全正确,8 位也是一个问题。不知道有多少 16 位机器有 C/Java 编译器,但我确信这比我 6 多年前写这个答案时要多。
    【解决方案4】:

    真正的答案:取决于您要查找的十六进制颜色值(例如 565、555、888、8888 等)、alpha 位的数量、实际颜色分布(rgb vs 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
    
    };
    };
    

    【讨论】:

      【解决方案5】:

      修改 Jeremy 的 python 答案以处理短 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】:

        您只需将值十六进制(部分)转换为十进制,反之亦然。还需要考虑,十六进制中的什么值可能包含 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 上的实现(适配 NodeJS 并支持 ES6)

        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'
        

        【讨论】:

          【解决方案7】:

          十六进制值只是以十六进制表示的 RGB 数字。因此,您只需将每对十六进制数字转换为十进制即可。

          例子:

          #FF6400 = RGB(0xFF, 0x64, 0x00) = RGB(255, 100, 0)
          

          【讨论】:

          • 他写了一个方程式。 RGB 到十六进制是从右到左读取。十六进制到 RGB 是从左到右读取的。
          【解决方案8】:
          #!/usr/bin/env python 重新进口 导入系统 def hex_to_rgb(值): value = value.lstrip('#') lv = len(值) return tuple(int(value[i:i+lv/3], 16) for i in range(0, lv, lv/3)) def rgb_to_hex(rgb): rgb = 评估(rgb) r = RGB[0] g = RGB[1] b = RGB[2] 返回 '​​#%02X%02X%02X' % (r,g,b) 定义主(): color = raw_input("HEX [#FFFFFF] 或 RGB [255, 255, 255] 值(没有值退出程序):") 而颜色: if 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]',颜色): 转换 = hex_to_rgb(颜色) 打印转换 elif re.search('[0-9]{1,3}, [0-9]{1,3}, [0-9]{1,3}', 颜色): 转换 = rgb_to_hex(颜色) 打印转换 elif 颜色 == '': 系统退出(0) 别的: print '您没有输入有效值!' color = raw_input("HEX [#FFFFFF] 或 RGB [255, 255, 255] 值(没有值退出程序):") 如果 __name__ == '__main__': 主要的()

          【讨论】:

            【解决方案9】:

            这是我在 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);
            

            【讨论】:

              【解决方案10】:

              非常简单和简短的实现:

              color_in_hex = 'FF00EE64' # Green Color
              print('RGB =', tuple(int(color_in_hex[i:i+2], 16) for i in (0, 2, 4)))
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2012-09-18
                • 2021-07-17
                • 2012-07-25
                • 1970-01-01
                • 2018-09-22
                • 2011-03-23
                • 2019-10-18
                • 2012-11-01
                相关资源
                最近更新 更多