Comment obtenir une valeur de couleur hexadécimale plutôt qu'une valeur RVB?


171

L'utilisation du jQuery suivant obtiendra la valeur RVB de la couleur d'arrière-plan d'un élément:

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

Existe-t-il un moyen d'obtenir la valeur hexadécimale plutôt que RVB?


2
Sur un sujet connexe, vous trouverez ici plus (et sans doute de meilleures) façons de convertir entre les couleurs hexadécimales et RVB: stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb Cette roue a été réinventée suffisamment de fois pour construire un train routier. J'espérais que l'une des bibliothèques JS populaires, plus simple que moins, aurait une fonction utilitaire.
Michael Scheper

Souvenez-vous que certains navigateurs renvoient rgba (#, #, #, #), comme rgba (0,0,0,0) qui est transparent, pas noir. La 4ème valeur est l'opacité, 1,0 étant 100% en couleur et 0,5 50%.
Twelve24

Réponses:


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

( Source )


7
+1, vous pouvez utiliser Number.toString (16) - au moins pour chaque chiffre hexadécimal (ou pad avec 0 si moins de 16 ans)
orip

19
-1. Comme mentionné par orip, vous pouvez utiliser toString (16). Évalué pour d'autres inefficacités. Si vous allez déclarer hexDigits à chaque appel de fonction, faites-le au moins dans le corps de la fonction de rgb2hex (pas dans le corps de hex), pour que le tableau ne soit pas redéfini 3 fois par 1 appel à rgb2hex. Apprenez également à utiliser «var» pour ne pas polluer la portée globale.
Matt

3
Cette méthode ne semble pas très tolérante aux espaces blancs ou aux majuscules différents. jsfiddle.net/Xotic750/pSQ7d
Xotic750

1
Si vous voulez vraiment être pédant, vous pouvez rendre l'expression régulière plus permissive: rgb.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i)Cependant, l'expression régulière donnée est conçue pour faire face au format donné par un navigateur lors de l'utilisation de jQuery, et cela n'a pas les différentes consistances d'espace blanc ou de captilisation. Tu es en train de parler de. Vous pouvez également utiliser le même regex et simplement supprimer tous les espaces et les convertir en minuscules avant de faire correspondre sur rgb. PS Votre exemple de violon: 'rgb (10, 128,)' Je ne pense pas que ce soit raisonnable de tester
reliure

et pour moi, le retour de jquery css background-colors est au format rgba, donc cela ne fonctionne pas.
Miguel

159

Voici la solution plus propre que j'ai écrite basée sur la suggestion @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]);
}

Certains navigateurs renvoient déjà les couleurs au format hexadécimal (à partir d'Internet Explorer 8 et inférieurs). Si vous devez gérer ces cas, ajoutez simplement une condition à l'intérieur de la fonction, comme @gfrobenius l'a suggéré:

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

Si vous utilisez jQuery et souhaitez une approche plus complète, vous pouvez utiliser les Hooks CSS disponibles depuis jQuery 1.4.3, comme je l'ai montré en répondant à cette question: Puis-je forcer les retours de jQuery.css ("backgroundColor") au format hexadécimal?


2
Je suggère à tout le monde: jetez un œil à ma réponse ici pour voir une version améliorée utilisant jQuery CSS Hooks .
Erick Petrucelli

1
@Ghigo, désolé mais vous vous trompez. IE8 retourne déjà les couleurs en hexadécimal lors de l' obtention du style actuel, de cette façon: document.getElementById("your_id").currentStyle["backgroundColor"]. La fonction rgb2hex()n'est pas nécessaire. Voici le plugin jQuery utilisant CSS Hooks que j'ai suggéré ci-dessus, qui effectue déjà toutes les validations pour récupérer les couleurs dans différents navigateurs: stackoverflow.com/questions/6177454/…
Erick Petrucelli

2
@Ghigo, je pense que vous avez mal compris: vous NE DEVRIEZ PAS utiliser cette fonction si vous êtes dans un navigateur qui retourne en HEX. Cette fonction convertit RVB en HEX et tout simplement. Ne l'utilisez pas lorsqu'il n'est pas en RVB. Le fait que vous ayez besoin d'une solution plus complète (qui détecte si la valeur est déjà RVB, comme l'a fait @ Jim-F) ne change pas le fait que cette solution offre exactement ce qui a été demandé par l'OP. Votre vote défavorable n'a aucun sens, désolé.
Erick Petrucelli

4
Je suis désolé mais je ne suis pas d'accord. Une fonction de navigateur croisé est toujours meilleure que celle qui nécessite une exécution basée sur la détection du navigateur. Op a demandé de convertir $('#selector').css('backgroundColor')en hexadécimal, pas une valeur RVB en hexadécimal. Et sur IE8, $('#selector').css('backgroundColor')est déjà hexadécimal donc il doit être manipulé. C'est tout. Ne vous fâchez pas contre moi :)
Ghigo

1
Faites ça les gars, une simple doublure que j'ai ajoutée à la rgb2hex()fonction, merci @ErickPetru! Je dois coder vers IE7, croyez-le ou non. Avec .css('backgroundColor')et obj.style.backgroundColorIE7 et 8 natifs renverront hex, pas RVB, j'ai donc ajouté ceci comme première ligne de la rgb2hex()fonction dans la réponse fournie pour que cela fonctionne jusqu'à 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 # symbolJ'espère que cela aide.
gfrobenius

61

La plupart des navigateurs semblent renvoyer la valeur RVB lors de l'utilisation:

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

Seul IE (seulement 6 testés jusqu'à présent) renvoie la valeur hexadécimale.

Pour éviter les messages d'erreur dans IE, vous pouvez envelopper la fonction dans une instruction 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
Celui-ci fonctionne mieux que la plupart des autres, car Jim prend en compte rgba, ce que Safari (du moins sur Mac OS X) utilise. Merci, Jim!
Pascal Lindelauf le

1
Excellente solution. Notez que la fonction renvoie des lettres minuscules, c'est-à-dire # ff5544 et non # FF5544.
Peter le

Cette expression régulière supportera également les canaux aplha dans la solution ci-dessus rgb = rgb.match (/ ^ rgba? ((\ D +), \ s * (\ d +), \ s * (\ d +) (?:, \ S *) (0 \. \ D +))?) $ /);
Henning Winter

travailler comme un charme
ucMedia

22

Mise à jour de @ErickPetru pour la compatibilité 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]);
}

J'ai mis à jour l'expression régulière pour qu'elle corresponde à la valeur alpha si définie, mais je ne l'utilise pas.


Juste pour être complet: je travaille sur un élément qui va exporter vers PowerPoint (ne demandez pas ...), et il accepte un quatrième octet sur la chaîne hexadécimale pour le canal alpha, donc on peut l'utiliser comme ceci: 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)) : ''); De plus, je supprime le #symbole pour le rendre indépendant de l'utilisation finale (on pourrait obtenir la sortie et l'ajouter 0xpar exemple, ou le laisser sans préfixe). J'espère que cela aide quelqu'un!
Óscar Gómez Alcañiz

10

Voici une ligne ES6 One qui n'utilise pas 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
Merci, cela m'a aidé à l'intégrer dans une page Wordpress qui supprime les barres obliques inverses des expressions régulières dans les réponses précédentes.
Jason le

5

Voici une version qui vérifie également la transparence, j'en avais besoin car mon objet était d'insérer le résultat dans un attribut de style, où la version transparente d'une couleur hexadécimale est en fait le mot "transparent".

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

Fonction qui renvoie la couleur d'arrière-plan d'un élément en hexadécimal.

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

exemple d'utilisation:

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

jsfiddle


4

Même réponse que @Jim F, mais syntaxe ES6 , donc moins d'instructions:

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

classe de couleur extraite du sélecteur de couleurs bootstrap

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

comment utiliser

var color = new Color("RGB(0,5,5)");
color.toHex()

3

Lisible && Reg-exp gratuit (pas de Reg-exp)

J'ai créé une fonction qui utilise des fonctions de base lisibles et aucune reg-exps.
La fonction accepte la couleur au format CSS hexadécimal, rgb ou rgba et renvoie une représentation hexadécimale.
EDIT: il y avait un bug avec l'analyse du format rgba (), corrigé ...

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

1
Ne fonctionne pas sur rgba (0,0,0,0). Premièrement: l'ordre doit changer .replace("rgba", "") .replace("rgb", "") .replace("(", "") .replace(")", "");Sinon, vous vous retrouvez avec a0,0,0,0. Et, il renvoie # 000000, qui est noir, au lieu de transparent.
Twelve24

Si la 4ème valeur d'un rgba est 0 (zéro), alors pour css pour cet 'élément' serait: element {color: # 000000, opacity: 0.0;} qui est transparent ou renvoie simplement conditionnellement le 'rgba (0,0 , 0,0) 'à l'appelant.
Twelve24

@ Twelve24 Parsing corrigé - j'ai en fait remarqué cela avant de lire votre commentaire, mais certainement merci pour cela :), Quant à la transparence - la fonction est censée renvoyer la couleur HEXA, ou la "couleur de base" - donc c'est exprès :)
jave.web

3

Essayer

// 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

Celui-ci a l'air un peu plus joli:

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

un one-liner plus succinct:

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

forçant jQuery à toujours retourner 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

Juste pour ajouter à la réponse de @ Justin ci-dessus.

ça devrait être

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('');

Comme les fonctions parse int ci-dessus tronquent les zéros non significatifs, produisant ainsi des codes de couleur incorrects de 5 ou 4 lettres peuvent être ... c'est-à-dire que pour rgb (216, 160, 10), il produit # d8a0a alors qu'il devrait être # d8a00a.

Merci


1

Voici une solution que j'ai trouvée qui ne génère pas d'erreurs de script dans IE: http://haacked.com/archive/2009/12/29/convert-rgb-to-hex.aspx


Dans les anciennes versions d'IE, la récupération d'une valeur de couleur d'un objet à l'aide de jquery peut parfois renvoyer hex au lieu de rgb, alors que la plupart des navigateurs modernes renvoient RVB. La fonction liée à gère les deux cas d'utilisation
Paul T

1

La réponse de Steven Pribilinskiy laisse tomber les zéros non significatifs, par exemple # ff0000 devient # ff00.

Une solution consiste à ajouter un 0 de début et une sous-chaîne des 2 derniers chiffres.

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

1

Puisque la question utilisait JQuery, voici un plugin JQuery basé sur le code de Daniel Elliott:

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

Utilisez-le comme:

var hexBackgroundColor = $('#myElement').cssAsHex('background-color');

0

Voici ma solution, fait également touppercase par l'utilisation d'un argument et vérifie d'autres espaces blancs possibles et la capitalisation dans la chaîne fournie.

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

Sur jsfiddle

Comparaison de vitesse sur jsperf

Une autre amélioration pourrait être trim()la rgbchaîne

var rxArray = rgb.trim().match(rx),

0

Ma belle solution non standard

HTML

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

jQuery

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

Résultat

#f5b405

1
Il renvoie tout dans le style. : c
Eddie
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.