2008-10-18 7 views

Répondre

10

vraie réponse: Cela dépend de quel type de valeur de couleur hexadécimale que vous recherchez (par exemple, 565, 555, 888, 8888, etc.), la quantité de bits alpha, la distribution réelle des couleurs (rgb vs bgr ...) et une tonne d'autres variables.

Voici un algorithme générique pour la plupart des valeurs RVB utilisant des modèles C++ (directement à partir de ScummVM).

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

Voici une struct couleur de l'échantillon pour 565 (le format standard pour les 16 bits couleurs):

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

Une valeur hexadécimale est juste des nombres RVB représentés en hexadécimal. Il vous suffit donc de prendre chaque paire de chiffres hexadécimaux et de les convertir en décimales.

Exemple:

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

Il a écrit une équation. RGB à hex est en train de lire de droite à gauche. Hex à RGB est en train de lire de gauche à droite. –

18

juste réel rapide:

int r = (hexcolor >> 16) & 0xFF; 

int g = (hexcolor >> 8) & 0xFF; 

int b = hexcolor & 0xFF; 

int hexcolor = (r << 16) + (g << 8) + b; 
+2

Attention à la précédence de votre opérateur: + a une priorité plus élevée que << –

+2

Est-ce que ce ne devrait pas être & &? –

+1

Nice .. réponse a été là depuis 1,5 ans et personne n'a attrapé cela. – billjamesdev

158

En 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' 
+1

Pourriez-vous expliquer ce qui se passe dans la mise en forme de 'rbg_to_hex'? – jpmc26

+2

Dans la fonction, rgb est un tuple de 3 ints. Cette chaîne de format est juste un # suivi par trois% 02x qui donne juste une valeur hexadécimale à deux chiffres de l'int. –

+4

J'ai posté cela il y a si longtemps et c'est toujours l'un de mes morceaux préférés de code python (que j'ai écrit) –

1
 
#!/usr/bin/env python 

import re 
import sys 

def hex_to_rgb(value): 
    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(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("HEX [#FFFFFF] or RGB [255, 255, 255] value (no value quits program): ") 
    while color: 
    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]', color): 
     converted = hex_to_rgb(color) 
     print converted 
    elif re.search('[0-9]{1,3}, [0-9]{1,3}, [0-9]{1,3}', color): 
     converted = rgb_to_hex(color) 
     print converted 
    elif color == '': 
     sys.exit(0) 
    else: 
     print 'You didn\'t enter a valid value!' 
    color = raw_input("HEX [#FFFFFF] or RGB [255, 255, 255] value (no value quits program): ") 

if __name__ == '__main__': 
    main() 
7

Modifier la réponse python de Jeremy pour gérer valeurs rgb CSS courtes comme 0, # 999 et #fff (que les navigateurs rendraient en noir, gris moyen et blanc):

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

Ceci est un fragment de code que j'ai créé pour mon propre usage dans C++ 11. vous pouvez envoyer des valeurs hexagonales ou des chaînes:

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

Dans la conversion python entre hex et 'rgb' est également inclus dans le package traçante matplotlib. A savoir

import matplotlib.colors as colors 

Puis

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

La mise en garde est que les valeurs rgb couleurs sont supposées être entre 0,0 et 1,0. Si vous voulez aller entre 0 et 255, vous devez faire une petite conversion. Plus précisément,

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

L'autre est à noter que colors.hex2color accepte uniquement les chaînes de couleur hexadécimal valides.

1

Vous avez seulement besoin de convertir une valeur hexadécimale (en parties) en décimal et vice-versa. Aussi besoin d'être considéré, quelle valeur en hexadécimal peut contenir 6 ou 3 caractères (sans le caractère '#').

Implémentation sur 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() 

mise en œuvre sur le JavaScript (adapté aux NodeJS avec un support 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; 

mise en œuvre sur le C (destiné au standart 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_); 
} 

Un résultat après compilation (je suis utilisé le 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' 
Questions connexes