Преобразовать значение цвета RGB в десятичное
Как преобразовать значение цвета RGB в обычное десятичное число?
Итак, у меня есть: RGB(255,255,255) белый
Его десятичный эквивалент: 16777215
Я пытался думать, что это может быть просто:
var dec = r*g*b; // but this doesn't work
Хотя это не работает.
Кто-нибудь знает алгоритм / уравнение для преобразования из RGB (или RGBA) в десятичную?
5 ответов
Целые числа RGB обычно обрабатываются как три различных байта, где самый левый (самый старший) байт красный, средний байт - зеленый, а самый правый (самый младший) байт - синий. Вы можете получить значения этих отдельных байтов следующим образом:
var c = 0xff03c0; // 16712640
var components = {
r: (c & 0xff0000) >> 16,
g: (c & 0x00ff00) >> 8,
b: (c & 0x0000ff)
};
Вы можете воссоздать цвет из его компонентов, вернув байты обратно:
c = (components.r << 16) + (components.g << 8) + (components.b);
В вашем случае просто подставьте components.r
(и т. д.) с вашими фактическими переменными.
Гораздо лучший ответ (с точки зрения ясности) заключается в следующем:
'Convert RGB to LONG:
LONG = B * 65536 + G * 256 + R
'Convert LONG to RGB:
B = LONG \ 65536
G = (LONG - B * 65536) \ 256
R = LONG - B * 65536 - G * 256
LONG - это ваше длинное целое (десятичное), которое вы хотите сделать. Полегче, а? Конечно, битшифт
Я согласен с тем, что bithift более четкий и, вероятно, лучше работает.
Тем не менее, если вы хотите получить математический ответ из-за языковой поддержки (например, сделать это в электронной таблице), modulus % и trunc() или floor() делают это простым:
Предполагая 8-битные значения для красного, зеленого и синего, конечно (0-255):
var rgbTotal = red * 65536 + green * 256 + blue;
var R = Math.trunc( rgbTotal / 65536 );
var G = Math.trunc( ( rgbTotal % 65536 ) / 256 );
var B = rgbTotal % 256;
Обсуждение: Указывая на ответ Сэма, значения RGB почти всегда имеют порядковый номер с прямым порядком, особенно на веб-страницах, jpeg и png. Лично я думаю, что лучше умножить красный на 65536 вместо синего, если вы не работаете с библиотекой, которая требует иного.
Чтобы вернуться к отдельным значениям:
- Для R просто разделите на 65536 и обрежьте остаток.
- Для G мы отбрасываем R через мод 65536, затем делим на 256, обрезая остаток (остаток - синий).
- Для B мы берем mod 256, который избавляется от двух старших байтов.
Для R & G число должно быть усечено, чтобы отбросить остаток, специфичный для языка, в основном нам нужно целое число. В javascript Math.trunc() является простым способом, и Math.floor() также работает. Это не нужно для B, так как это остаток от модуля - однако это также предполагает, что нам не нужна проверка ошибок, например, из пользовательского ввода, то есть значение для B всегда является целым числом 0-255.
var dec = (b & 0xff) << 16 + (g & 0xff) << 8 + (r & 0xff);
(Я думаю, что это правильный порядок значений r, g, b)
Обновить
Я только что проверил на наличие приложений для браузера и неправильно понял порядок, поэтому правильная формула для браузеров (читайте HTML+CSS+javascript):
var dec = r << 16 + g << 16 + b;
Предполагая значения r, g, b <= 255
Другие API могут ожидать другого порядка для значений r, g, b. Кажется, я помню, по крайней мере, тот, в котором порядок был изменен (согласно моему первоначальному ответу), но я думаю, какой это на данный момент.
if (color.substr(0, 1) === '#') {
return color;
}
var digits = /(.*?)rgb\((\d+), (\d+), (\d+)\)/.exec(color);
var red = parseInt(digits[2]);
var green = parseInt(digits[3]);
var blue = parseInt(digits[4]);
var rgb = blue | (green << 8) | (red << 16);
return rgb.toString(10);
Вам нужно сдвинуть влево R на 16, G влево на 8 и / или оба на B. Посмотрите на значения как биты, и все станет ясно:
R 255 = 11111111B G 255 = 11111111B B 255 = 11111111B
Сдвиг R 16: 111111110000000000000000 Сдвиг G 8: 000000001111111100000000
или в B: 111111111111111111111111
Преобразовать в десятичное число: 16777215