Как получить шестнадцатеричное значение цвета, а не значение RGB?

171

Используя следующий jQuery, вы получите значение RGB цвета фона элемента:

$('#selector').css('backgroundColor');

Есть ли способ получить шестнадцатеричное значение, а не RGB?

bfavaretto
источник
2
На смежную тему, более (и, возможно, лучше) способы преобразования между цветами hex и RGB здесь: stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb Это колесо было изобретено достаточно много раз построить автопоезд. Я надеялся, что одна из популярных библиотек JS, проще, чем меньше, будет иметь функцию полезности.
Майкл Шепер
Помните, что некоторые браузеры возвращают rgba (#, #, #, #), например, rgba (0,0,0,0), который является прозрачным, а не черным. 4-е значение - непрозрачность, при этом значение 1.0 соответствует цвету 100%, а 0,5 - 50%.
Двенадцать24

Ответы:

141
var hexDigits = new Array
        ("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"); 

//Function to convert rgb color to hex format
function rgb2hex(rgb) {
 rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
 return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
}

function hex(x) {
  return isNaN(x) ? "00" : hexDigits[(x - x % 16) / 16] + hexDigits[x % 16];
 }

( Источник )

Даниэль Эллиотт
источник
7
+1, вы можете использовать Number.toString (16) - по крайней мере, для каждой шестнадцатеричной цифры (или pad с 0, если меньше 16)
orip
19
-1. Как упоминалось в orip, вы можете использовать toString (16). Проголосовал за другие неэффективности. Если вы собираетесь объявлять hexDigits при каждом вызове функции, по крайней мере, делайте это в теле функции rgb2hex (не в теле hex), чтобы массив не переопределялся 3 раза за 1 вызов rgb2hex. Также научитесь использовать «var», чтобы не загрязнять глобальный охват.
Мэтт
3
Этот метод не выглядит слишком терпимым к различным пробелам или заглавным буквам. jsfiddle.net/Xotic750/pSQ7d
Xotic750
1
Если вы действительно хотите быть педантичным, вы можете сделать регулярное выражение более допустимым: rgb.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i)однако данное регулярное выражение предназначено для того, чтобы справляться с форматом, заданным браузером при использовании jQuery, и у него нет различий между пробелами и опознавательными знаками Вы говорите о. Вы также можете использовать то же регулярное выражение и просто удалить все пробелы и преобразовать в нижний регистр перед сопоставлением на rgb. PS Ваш пример с скрипкой: 'rgb (10, 128,)' Я не думаю, что это разумно для тестирования
переплет
и для меня возвращение jquery css background-colors приходит в формате с rgba, так что это не работает.
Мигель
159

Вот более чистое решение, которое я написал на основе предложения @Matt:

function rgb2hex(rgb) {
    rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
    function hex(x) {
        return ("0" + parseInt(x).toString(16)).slice(-2);
    }
    return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
}

Некоторые браузеры уже возвращают цвета в шестнадцатеричном формате (начиная с Internet Explorer 8 и ниже). Если вам нужно разобраться с этими случаями, просто добавьте условие внутри функции, как предложено @gfrobenius:

function rgb2hex(rgb) {
    if (/^#[0-9A-F]{6}$/i.test(rgb)) return rgb;

    rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
    function hex(x) {
        return ("0" + parseInt(x).toString(16)).slice(-2);
    }
    return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
}

Если вы используете jQuery и хотите более полный подход, вы можете использовать CSS-хуки, доступные с jQuery 1.4.3, как я показал, отвечая на этот вопрос: могу ли я принудительно вернуть jQuery.css ("backgroundColor") в шестнадцатеричном формате?

Эрик Петручелли
источник
2
Я предлагаю всем: взгляните на мой ответ здесь, чтобы увидеть улучшенную версию с использованием jQuery CSS Hooks .
Эрик Петручелли
1
@ Гиго, прости, но ты не прав. IE8 уже возвращает цвета , как шестнадцатеричные при получении текущего стиля, таким образом: document.getElementById("your_id").currentStyle["backgroundColor"]. Функция rgb2hex()не нужна. Вот плагин jQuery с использованием CSS-хуков, которые я предложил выше, который уже выполняет все проверки для восстановления цветов в разных браузерах: stackoverflow.com/questions/6177454/…
Erick Petrucelli
2
@Ghigo, я думаю, вы неправильно поняли: вы НЕ ДОЛЖНЫ использовать эту функцию, если вы находитесь в браузере, который возвращает HEX. Эта функция конвертирует RGB в HEX и только его. Не используйте его, когда он не в RGB. Тот факт, что вам нужно более полное решение (которое определяет, является ли значение уже как RGB, как сделано @ Jim-F), не меняет того факта, что это решение предлагает именно то, что было запрошено OP. Твое понижение не имеет смысла, извини.
Эрик Петручелли,
4
Извините, но я не согласен. Кросс-браузерная функция всегда лучше, чем та, которая требует выполнения на основе определения браузера. Оператор попросил преобразовать $('#selector').css('backgroundColor')в гекс, а не значение rgb в гекс. И на IE8, $('#selector').css('backgroundColor')уже шестнадцатеричный, поэтому он должен быть обработан. Вот и все. Не сердитесь на меня :)
Ghigo
1
Сделайте это, ребята, простой вкладыш, который я добавил в rgb2hex()функцию, спасибо @ErickPetru! Я должен написать код обратно в IE7, хотите верьте, хотите нет. С .css('backgroundColor')и родные obj.style.backgroundColorIE7 & 8 будут возвращать hex, а не RGB, поэтому я добавил это в качестве первой строки rgb2hex()функции в поставляемом ответе, чтобы она работала вплоть до IE7: /* IE7&8 will return hex, so no need to run this function if it is already hex. */ if (/^#[0-9A-F]{6}$/i.test(rgb)) return rgb.substring(1, 7); //I'm doing a subtring here because I do not want the leading # symbolнадеюсь, это поможет.
Гфробениус
61

Большинство браузеров, похоже, возвращают значение RGB при использовании:

$('#selector').css('backgroundColor');

Только IE (пока протестировано только 6) возвращает значение Hex.

Чтобы избежать сообщений об ошибках в IE, вы можете заключить функцию в оператор if:

function rgb2hex(rgb) {
     if (  rgb.search("rgb") == -1 ) {
          return rgb;
     } else {
          rgb = rgb.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+))?\)$/);
          function hex(x) {
               return ("0" + parseInt(x).toString(16)).slice(-2);
          }
          return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]); 
     }
}
Джим Ф
источник
1
Этот работает лучше, чем большинство других, так как Джим принимает во внимание rgba, что и использует Safari (по крайней мере, в Mac OS X). Спасибо, Джим!
Паскаль Линделауф
1
Отличное решение. Обратите внимание, что функция возвращает строчные буквы, т.е. # ff5544, а не # FF5544.
Питер
Это регулярное выражение будет поддерживать каналы aplha также в приведенном выше решении rgb = rgb.match (/ ^ rgba? ((\ D +), \ s * (\ d +), \ s * (\ d +) (?:, \ S *) (0 \ \ d +.))) $ /?);
Хеннинг зимой
работать как шарм
ucMedia
22

Обновлен @ErickPetru для совместимости с rgba:

function rgb2hex(rgb) {
    rgb = rgb.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+))?\)$/);
    function hex(x) {
        return ("0" + parseInt(x).toString(16)).slice(-2);
    }
    return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
}

Я обновил регулярное выражение для соответствия альфа-значению, если оно определено, но не использую его.

Зак Кац
источник
Просто для полноты: я работаю над тем, что будет экспортировать в PowerPoint (не спрашивайте ...), и он принимает четвертый байт шестнадцатеричной строки для альфа-канала, поэтому можно использовать его следующим образом: return hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]) /* Add the alpha channel if it exists */ + (rgb[5] !== undefined ? hex(Math.round(rgb[5] * 255)) : ''); Также я удаляю #символ, чтобы сделать его независимым от конечного использования (можно получить вывод и, 0xнапример, добавить к нему префикс или оставить его без префикса). Надеюсь, это поможет кому-то!
Оскар Гомес Альканьис
10

Вот один лайнер ES6, который не использует jQuery:

var rgb = document.querySelector('#selector').style['background-color'];
return '#' + rgb.substr(4, rgb.indexOf(')') - 4).split(',').map((color) => parseInt(color).toString(16)).join('');
Джастин Маккэндлесс
источник
1
Спасибо, это помогло мне включить его в страницу Wordpress, которая удаляет обратные слеши регулярных выражений в предыдущих ответах.
Джейсон
5

Вот версия, которая также проверяет прозрачность, я нуждался в этом, поскольку мой объект должен был вставить результат в атрибут стиля, где прозрачная версия шестнадцатеричного цвета на самом деле является словом «прозрачный» ..

function rgb2hex(rgb) {
     if (  rgb.search("rgb") == -1 ) {
          return rgb;
     }
     else if ( rgb == 'rgba(0, 0, 0, 0)' ) {
         return 'transparent';
     }
     else {
          rgb = rgb.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+))?\)$/);
          function hex(x) {
               return ("0" + parseInt(x).toString(16)).slice(-2);
          }
          return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]); 
     }
}
Мэтт Веландер
источник
4

Функция, которая возвращает цвет фона элемента в шестнадцатеричном виде.

function getBgColorHex(elem){
    var color = elem.css('background-color')
    var hex;
    if(color.indexOf('#')>-1){
        //for IE
        hex = color;
    } else {
        var rgb = color.match(/\d+/g);
        hex = '#'+ ('0' + parseInt(rgb[0], 10).toString(16)).slice(-2) + ('0' + parseInt(rgb[1], 10).toString(16)).slice(-2) + ('0' + parseInt(rgb[2], 10).toString(16)).slice(-2);
    }
    return hex;
}

пример использования:

$('#div1').click(function(){
   alert(getBgColorHex($(this));
}

jsfiddle

Шаик
источник
4

Тот же ответ, что и у @Jim F, но с синтаксисом ES6 , поэтому меньше инструкций:

const rgb2hex = (rgb) => {
  if (rgb.search("rgb") === -1) return rgb;
  rgb = rgb.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+))?\)$/);
  const hex = (x) => ("0" + parseInt(x).toString(16)).slice(-2);
  return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
};
Абденнур ТУМИ
источник
3

цветовой класс, взятый из палитры начальной загрузки

// Color object
var Color = function(val) {
    this.value = {
        h: 1,
        s: 1,
        b: 1,
        a: 1
    };
    this.setColor(val);
};

Color.prototype = {
    constructor: Color,

    //parse a string to HSB
    setColor: function(val){
        val = val.toLowerCase();
        var that = this;
        $.each( CPGlobal.stringParsers, function( i, parser ) {
            var match = parser.re.exec( val ),
            values = match && parser.parse( match ),
            space = parser.space||'rgba';
            if ( values ) {
                if (space === 'hsla') {
                    that.value = CPGlobal.RGBtoHSB.apply(null, CPGlobal.HSLtoRGB.apply(null, values));
                } else {
                    that.value = CPGlobal.RGBtoHSB.apply(null, values);
                }
                return false;
            }
        });
    },

    setHue: function(h) {
        this.value.h = 1- h;
    },

    setSaturation: function(s) {
        this.value.s = s;
    },

    setLightness: function(b) {
        this.value.b = 1- b;
    },

    setAlpha: function(a) {
        this.value.a = parseInt((1 - a)*100, 10)/100;
    },

    // HSBtoRGB from RaphaelJS
    // https://github.com/DmitryBaranovskiy/raphael/
    toRGB: function(h, s, b, a) {
        if (!h) {
            h = this.value.h;
            s = this.value.s;
            b = this.value.b;
        }
        h *= 360;
        var R, G, B, X, C;
        h = (h % 360) / 60;
        C = b * s;
        X = C * (1 - Math.abs(h % 2 - 1));
        R = G = B = b - C;

        h = ~~h;
        R += [C, X, 0, 0, X, C][h];
        G += [X, C, C, X, 0, 0][h];
        B += [0, 0, X, C, C, X][h];
        return {
            r: Math.round(R*255),
            g: Math.round(G*255),
            b: Math.round(B*255),
            a: a||this.value.a
        };
    },

    toHex: function(h, s, b, a){
        var rgb = this.toRGB(h, s, b, a);
        return '#'+((1 << 24) | (parseInt(rgb.r) << 16) | (parseInt(rgb.g) << 8) | parseInt(rgb.b)).toString(16).substr(1);
    },

    toHSL: function(h, s, b, a){
        if (!h) {
            h = this.value.h;
            s = this.value.s;
            b = this.value.b;
        }
        var H = h,
        L = (2 - s) * b,
        S = s * b;
        if (L > 0 && L <= 1) {
            S /= L;
        } else {
            S /= 2 - L;
        }
        L /= 2;
        if (S > 1) {
            S = 1;
        }
        return {
            h: H,
            s: S,
            l: L,
            a: a||this.value.a
        };
    }
};

как пользоваться

var color = new Color("RGB(0,5,5)");
color.toHex()
Фарид Алнамрути
источник
3

Читаемый && Reg-exp бесплатно (без Reg-exp)

Я создал функцию, которая использует удобочитаемые базовые функции и не использует регулярные выражения.
Функция принимает цвет в шестнадцатеричном, rgb или rgba CSS-формате и возвращает шестнадцатеричное представление.
РЕДАКТИРОВАТЬ: была ошибка при разборе формата rgba (), исправлено ...

function getHexColor( color ){
    //if color is already in hex, just return it...
    if( color.indexOf('#') != -1 ) return color;
    
    //leave only "R,G,B" :
    color = color
                .replace("rgba", "") //must go BEFORE rgb replace
                .replace("rgb", "")
                .replace("(", "")
                .replace(")", "");
    color = color.split(","); // get Array["R","G","B"]
    
    // 0) add leading #
    // 1) add leading zero, so we get 0XY or 0X
    // 2) append leading zero with parsed out int value of R/G/B
    //    converted to HEX string representation
    // 3) slice out 2 last chars (get last 2 chars) => 
    //    => we get XY from 0XY and 0X stays the same
    return  "#"
            + ( '0' + parseInt(color[0], 10).toString(16) ).slice(-2)
            + ( '0' + parseInt(color[1], 10).toString(16) ).slice(-2)
            + ( '0' + parseInt(color[2], 10).toString(16) ).slice(-2);
}
jave.web
источник
1
Не работает на rgba (0,0,0,0). Во-первых: порядок должен измениться. .replace("rgba", "") .replace("rgb", "") .replace("(", "") .replace(")", "");В противном случае вы получите a0,0,0,0. И он возвращает # 000000, который является черным, а не прозрачным.
Двенадцать24
Если 4-е значение в rgba равно 0 (нулю), то для css для этого «элемента» будет: element {color: # 000000, opacity: 0.0;}, который является прозрачным или просто условно возвращает 'rgba (0,0 0,0) вернуться к звонящему.
Двенадцать24
@ Twelve24 Исправлен синтаксический анализ - я действительно заметил, что перед прочтением вашего комментария, но определенно спасибо за это :), Что касается прозрачности - функция должна возвращать цвет HEXA или "базовый цвет" - так, чтобы он был нарочно :)
jave.web
3

Пытаться

// c - color str e.g."rgb(12,233,43)", result color hex e.g. "#0ce92b"
let rgb2hex= c=> '#'+c.match(/\d+/g).map(x=>(+x).toString(16).padStart(2,0)).join``

Камил Келчевски
источник
2

Этот выглядит немного лучше:

var rgb = $('#selector').css('backgroundColor').match(/\d+/g);
var r   = parseInt(rgb[0], 10);
var g   = parseInt(rgb[1], 10);
var b   = parseInt(rgb[2], 10);
var hex = '#'+ r.toString(16) + g.toString(16) + b.toString(16);

более лаконичная строчка:

var rgb = $('#selector').css('backgroundColor').match(/\d+/g);
var hex = '#'+ Number(rgb[0]).toString(16) + Number(rgb[1]).toString(16) + Number(rgb[2]).toString(16);

заставляя jQuery всегда возвращать hex:

$.cssHooks.backgroundColor = {
    get: function(elem) {
        if (elem.currentStyle)
            var bg = elem.currentStyle["backgroundColor"];
        else if (window.getComputedStyle) {
            var bg = document.defaultView.getComputedStyle(elem,
                null).getPropertyValue("background-color");
        }
        if (bg.search("rgb") == -1) {
            return bg;
        } else {
            bg = bg.match(/\d+/g);
            function hex(x) {
                return ("0" + parseInt(x).toString(16)).slice(-2);
            }
            return "#" + hex(bg[0]) + hex(bg[1]) + hex(bg[2]);
        }
    }
}
Стивен Прибилинский
источник
2

Просто чтобы добавить ответ @ Джастина выше ..

так должно быть

var rgb = document.querySelector('#selector').style['background-color'];
return '#' + rgb.substr(4, rgb.indexOf(')') - 4).split(',').map((color) => String("0" + parseInt(color).toString(16)).slice(-2)).join('');

Поскольку вышеприведенные функции parse int обрезают начальные нули, таким образом выдают неправильные цветовые коды из 5 или 4 букв, которые могут быть ... т.е. для rgb (216, 160, 10) он выдает # d8a0a, тогда как он должен быть # d8a00a.

Спасибо

Йогеш Кумар Гупта
источник
1

Вот решение, которое я нашел, которое не выдает ошибки скриптинга в IE: http://haacked.com/archive/2009/12/29/convert-rgb-to-hex.aspx

Майк
источник
В более старых версиях IE выбор значения цвета объекта с использованием jquery иногда может возвращать hex вместо rgb, в то время как большинство современных браузеров возвращают RGB. Связанный с функцией обрабатывает оба варианта использования
Пол Т
1

Ответ Стивена Прибилинского отбрасывает ведущие нули, например # ff0000 становится # ff00.

Решение состоит в том, чтобы добавить начальный 0 и подстроку из последних 2 цифр.

var rgb = $('#selector').css('backgroundColor').match(/\d+/g);
var hex = '#'+ String('0' + Number(rgb[0]).toString(16)).slice(-2) + String('0' + Number(rgb[1]).toString(16)).slice(-2) + String('0' + Number(rgb[2]).toString(16)).slice(-2);
user2874310
источник
1

Поскольку вопрос касался использования JQuery, вот плагин JQuery, основанный на коде Дэниела Эллиотта:

$.fn.cssAsHex = function(colorProp) {

    var hexDigits = '0123456789abcdef';

    function hex(x) {
        return isNaN(x) ? '00' : hexDigits[(x - x % 16) / 16] + hexDigits[x % 16];
    };

    // Convert RGB color to Hex format
    function rgb2hex(rgb) {
        var rgbRegex = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
        return '#' + hex(rgbRegex[1]) + hex(rgbRegex[2]) + hex(rgbRegex[3]);
    };

    return rgb2hex(this.css(colorProp));
};

Используйте это как:

var hexBackgroundColor = $('#myElement').cssAsHex('background-color');
Том Сёдерлунд
источник
0

Здесь мое решение, также делает touppercase с помощью аргумента и проверяет другие возможные пробелы и заглавные буквы в предоставленной строке.

var a = "rgb(10, 128, 255)";
var b = "rgb( 10, 128, 255)";
var c = "rgb(10, 128, 255 )";
var d = "rgb ( 10, 128, 255 )";
var e = "RGB ( 10, 128, 255 )";
var f = "rgb(10,128,255)";
var g = "rgb(10, 128,)";

var rgbToHex = (function () {
    var rx = /^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i;

    function pad(num) {
        if (num.length === 1) {
            num = "0" + num;
        }

        return num;
    }

    return function (rgb, uppercase) {
        var rxArray = rgb.match(rx),
            hex;

        if (rxArray !== null) {
            hex = pad(parseInt(rxArray[1], 10).toString(16)) + pad(parseInt(rxArray[2], 10).toString(16)) + pad(parseInt(rxArray[3], 10).toString(16));

            if (uppercase === true) {
                hex = hex.toUpperCase();
            }

            return hex;
        }

        return;
    };
}());

console.log(rgbToHex(a));
console.log(rgbToHex(b, true));
console.log(rgbToHex(c));
console.log(rgbToHex(d));
console.log(rgbToHex(e));
console.log(rgbToHex(f));
console.log(rgbToHex(g));

На jsfiddle

Сравнение скорости на jsperf

Дальнейшее улучшение может быть trim()в rgbстроку

var rxArray = rgb.trim().match(rx),
Xotic750
источник
0

Мое красивое нестандартное решение

HTML

<div id="selector" style="background-color:#f5b405"></div>

JQuery

$("#selector").attr("style").replace("background-color:", "");

результат

#f5b405
Newred
источник
1
Он возвращает все в стиле. : c
Эдди