Convertendo a cor hexadecimal em RGB e vice-versa

Qual é a maneira mais eficiente de fazer isso?

Resposta real: Depende do tipo de valor de cor hexadecimal que você está procurando (por exemplo, 565, 555, 888, 8888, etc), a quantidade de bits alfa, a distribuição de cor real (rgb vs bgr …) e uma tonelada de outras variables.

Aqui está um algoritmo genérico para a maioria dos valores RGB usando modelos C ++ (diretamente do ScummVM).

template 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); } 

Aqui está uma amostra de estrutura de colors para 565 (o formato padrão para colors de 16 bits):

 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 }; }; 

Em 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' 

Em python, a conversão entre hex e ‘rgb’ também é incluída no pacote de plotagem matplotlib . Nomeadamente

 import matplotlib.colors as colors 

Então

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

A ressalva é que os valores de rgb nas colors são considerados entre 0,0 e 1,0. Se você quiser ir entre 0 e 255, você precisa fazer uma pequena conversão. Especificamente,

 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]) 

A outra nota é que colors.hex2color só aceita strings de colors hexadecimais válidas.

apenas bem rápido:

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

Modificando a resposta python de Jeremy para manipular valores curtos de CSS rgb como 0, # 999 e #fff (que os navegadores renderizariam como preto, cinza médio e branco):

 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)) 

Um valor hexadecimal é apenas um número RGB representado em hexadecimal. Então você só precisa pegar cada par de dígitos hexadecimais e convertê-los em decimal.

Exemplo:

 #FF6400 = RGB(0xFF, 0x64, 0x00) = RGB(255, 100, 0) 
 #! / usr / bin / env python

 importação re
 import sys

 def hex_to_rgb (valor):
   value = value.lstrip ('#')
   lv = len (valor)
   return tuple (int (valor [i: i + lv / 3], 16) para i no intervalo (0, lv, lv / 3))

 def rgb_to_hex (rgb):
   rgb = eval (rgb)
   r = rgb [0]
   g = rgb [1]
   b = rgb [2]
   return '#% 02X% 02X% 02X'% (r, g, b)

 def main ():
   color = raw_input ("valor HEX [#FFFFFF] ou RGB [255, 255, 255] (nenhum valor sai do programa):")
   enquanto cor:
     se 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] ', cor):
       convertido = hex_to_rgb (cor)
       imprimir convertido
     elif re.search ('[0-9] {1,3}, [0-9] {1,3}, [0-9] {1,3}', cor):
       convertido = rgb_to_hex (cor)
       imprimir convertido
     cor elif == '':
       sys.exit (0)
     outro:
       print 'Você não digitou um valor válido!'
     color = raw_input ("valor HEX [#FFFFFF] ou RGB [255, 255, 255] (nenhum valor sai do programa):")

 se __name__ == '__main__':
   a Principal()

Este é um fragment de código que criei para uso próprio em c ++ 11. você pode enviar valores hexadecimais ou strings:

  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); 

Você só precisa converter um valor hex (em partes) em decimal e vice-versa. Também precisa considerar, qual valor em hexadecimal pode conter 6 ou 3 caracteres (sem caractere ‘#’).

Implementação no 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() 

Implementação no JavaScript (adaptado ao NodeJS com suporte ao 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; 

Implementação no C (destinado ao padrão 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_); } 

Um resultado depois de compilation (eu sou usado o 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'