これを行う最も効率的な方法は何ですか?
実際の答え:探している16進数の色の値の種類(たとえば、565、555、888、8888など)、アルファビットの量、実際の色分布(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
};
};
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'
In python hexと '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])
もう1つの注意点は、colors.hex2color
は、有効な16進数の色の文字列のみを受け入れます。
本当に速い:
int r = ( hexcolor >> 16 ) & 0xFF;
int g = ( hexcolor >> 8 ) & 0xFF;
int b = hexcolor & 0xFF;
int hexcolor = (r << 16) + (g << 8) + b;
Jeremyのpython answerを変更して、0、#999、#fffなどの短いCSS rgb値を処理します(ブラウザは黒、中間の灰色、白としてレンダリングします)):
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))
16進数の値は、16進数で表されたRGB番号です。そのため、16進数の各ペアを取得して、10進数に変換する必要があります。
例:
#FF6400 = RGB(0xFF, 0x64, 0x00) = RGB(255, 100, 0)
値の16進数(一部)を10進数に、またはその逆に変換するだけです。また、16進数のどの値に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 __== '__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'
これは、c ++ 11で使用するために作成したコードのフラグメントです。 16進値または文字列を送信できます。
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);
#!/ 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範囲内(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]またはRGB [255、255、255]値(値はプログラムを終了しません):") 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] '、色): 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変換済み Elif color == '': sys.exit(0) else: print 'You did \' t有効な値を入力してくださいe! ' color = raw_input( "HEX [#FFFFFF]またはRGB [255、255、255]値(値はプログラムを終了しません):") if __ = = '__main __': main()