2008-10-18 20 views

Respuesta

10

respuesta real: Depende de qué tipo de valor hexadecimal del color que busca (por ejemplo, 565, 555, 888, 8888, etc.), la cantidad de bits alfa, la distribución de color real (rgb vs bgr ...) y una tonelada de otras variables.

Aquí hay un algoritmo genérico para la mayoría de los valores RGB usando plantillas C++ (directamente desde 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); 
} 

Aquí hay una estructura de color de la muestra de 565 (el formato estándar para colores 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 

}; 
}; 
2

Un valor hexadecimal es solo números RGB representados en hexadecimal. Entonces solo tienes que tomar cada par de dígitos hexadecimales y convertirlos a decimal.

Ejemplo:

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

Escribió una ecuación. RGB a hexadecimal está leyendo de derecha a izquierda. Hex a RGB está leyendo de izquierda a derecha. –

18

acaba muy rápido:

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

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

int b = hexcolor & 0xFF; 

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

Cuidando la precedencia de su operador: + tiene mayor prioridad que << –

+2

¿No deberían ser y no &&? –

+1

Niza ... la respuesta ha estado ahí por 1,5 años y nadie lo entendió. – 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

¿Podría explicar lo que está sucediendo en el formateo de 'rbg_to_hex'? – jpmc26

+2

En la función, rgb es una tupla de 3 ints. Esa cadena de formato es solo un # seguido de un 3% 02x que simplemente da un valor hexadecimal de 2 dígitos rellenado de cero del int. –

+4

He publicado esto hace tanto tiempo y sigue siendo uno de mis fragmentos favoritos de código python (que he escrito) –

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

Modificación de respuesta pitón de Jeremy para manejar valores cortos de rgb de CSS como 0, # 999 y #fff (que los navegadores mostrarían como negro, gris medio y blanco):

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

Este es un fragmento de código que he creado para mi propio uso en C++ 11. puede enviar valores hexadecimales o cadenas:

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

En la conversión pitón entre hexadecimal y 'RGB' también se incluye en el paquete de trazado matplotlib. A saber

import matplotlib.colors as colors 

Entonces

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

La advertencia es que los valores RGB en colores se supone que son entre 0,0 y 1,0. Si quiere ir entre 0 y 255, necesita hacer una pequeña conversión. En concreto,

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

La otra cosa es que colors.hex2color sólo acepta cadenas de color hexadecimal válido.

1

Solo necesita convertir un valor hexadecimal (en partes) a decimal y viceversa. También se necesita considerar, qué valor en hex puede contener 6 o 3 caracteres (sin el carácter '#').

Implementación en 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() 

Ejecución sobre la JavaScript (adaptado a las NodeJS con un soporte 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; 

Ejecución sobre la C (destinada a la 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 resultado después de la compilación (se me usa el 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' 
Cuestiones relacionadas