将hex颜色转换为RGB,反之亦然
什么是最有效的方式来做到这一点?
真正的答案:取决于你正在寻找什么样的hex颜色值(例如565,555,888,8888等),阿尔法位的数量,实际颜色分布(rgb vs bgr …)和一吨其他variables。
下面是使用C ++模板(直接来自ScummVM)的大多数RGB值的通用algorithm。
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 }; };
在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'
在十进制和'rgb'之间的python转换也包含在绘图包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
只接受有效的hex颜色string。
只是真的很快:
int r = ( hexcolor >> 16 ) & 0xFF; int g = ( hexcolor >> 8 ) & 0xFF; int b = hexcolor & 0xFF; int hexcolor = (r << 16) + (g << 8) + b;
修改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))
hex值只是以hex表示的RGB数字。 所以你只需要把每一对hex数字,并将其转换为十进制。
例:
#FF6400 = RGB(0xFF, 0x64, 0x00) = RGB(255, 100, 0)
#!/ usr / bin / env python 导入重新 导入系统 def hex_to_rgb(value): value = value.lstrip('#') lv = len(value) 对于范围(0,lv,lv / 3)中的i,返回元组(int(value [i:i + lv / 3],16)) def rgb_to_hex(rgb): rgb = eval(rgb) r = rgb [0] g = rgb [1] b = rgb [2] 返回'#%02X%02X%02X'%(r,g,b) def main(): color = raw_input(“HEX [#FFFFFF] or RGB [255,255,255] value(no value quits program):”) 而颜色: 如果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}',color): 转换= rgb_to_hex(颜色) 打印转换 elif color =='': sys.exit(0) 其他: 打印“你没有input有效的值!” color = raw_input(“HEX [#FFFFFF] or RGB [255,255,255] value(no value quits program):”) 如果__name__ =='__main__': 主要()
这是我为自己在c ++ 11中创build的代码片段。 你可以发送hex值或string:
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);
您只需将hex值(以分钟为单位)转换为十进制,反之亦然。 还需要考虑,hex中的值可能包含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'