Come ottenere il valore del colore esadecimale anziché il valore RGB?


171

Utilizzando il seguente jQuery otterrai il valore RGB del colore di sfondo di un elemento:

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

C'è un modo per ottenere il valore esadecimale piuttosto che RGB?


2
Su un argomento correlato, ci sono altri (e probabilmente migliori) modi per convertire tra colori esadecimali e RGB: stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb Questa ruota è stata reinventata abbastanza volte per costruire un treno stradale. Speravo che una delle librerie JS più popolari, più semplice di meno, avrebbe avuto una funzione di utilità.
Michael Scheper,

Ricorda che alcuni browser restituiscono rgba (#, #, #, #), come rgba (0,0,0,0) che è trasparente, non nero. Il 4o valore è l'opacità, con 1,0 che è a colori al 100% e 0,5 che è al 50%.
Dodici24,

Risposte:


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

( Fonte )


7
+1, potresti usare Number.toString (16) - almeno per ogni cifra esadecimale (o pad con 0 se sotto i 16 anni)
orip

19
-1. Come accennato da orip, è possibile utilizzare toString (16). Downvoted per altre inefficienze. Se hai intenzione di dichiarare hexDigits su ogni chiamata di funzione, almeno fallo nel corpo della funzione di rgb2hex (non nel corpo di hex), quindi l'array non viene ridefinito 3 volte per 1 chiamata a rgb2hex. Impara anche a usare 'var', in modo da non inquinare l'ambito globale.
Matt,

3
Questo metodo non sembra molto tollerante nei confronti degli spazi bianchi o delle maiuscole. jsfiddle.net/Xotic750/pSQ7d
Xotic750

1
Se vuoi davvero essere pedante, puoi rendere la regex più permissiva: rgb.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i)tuttavia, la regex fornita è progettata per far fronte al formato fornito da un browser quando si utilizza jQuery e questo non ha le diverse consistenze di spazi bianchi o captilizzazione stai parlando di. Puoi anche usare lo stesso regex e rimuovere tutti gli spazi bianchi e convertirli in minuscolo prima di abbinare su rgb. PS Il tuo esempio di violino: 'rgb (10, 128,)' Non penso che sia ragionevole testarlo
rilegato il

e per me il ritorno di jquery css background-colors è disponibile in formato con rgba, quindi non funziona.
Miguel,

159

Ecco la soluzione più pulita che ho scritto sulla base del suggerimento @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]);
}

Alcuni browser restituiscono già i colori come esadecimali (a partire da Internet Explorer 8 e versioni precedenti). Se hai bisogno di occuparti di questi casi, aggiungi semplicemente una condizione all'interno della funzione, come suggerito da @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]);
}

Se stai usando jQuery e desideri un approccio più completo, puoi utilizzare CSS Hooks disponibili da jQuery 1.4.3, come ho mostrato quando ho risposto a questa domanda: Posso forzare il ritorno di jQuery.css ("backgroundColor") in formato esadecimale?


2
Consiglio a tutti: dai un'occhiata alla mia risposta qui per vedere una versione migliorata usando i ganci CSS di jQuery .
Erick Petrucelli,

1
@Ghigo, scusa ma ti sbagli. IE8 torna già colori come esadecimale quando ottiene lo stile corrente, in questo modo: document.getElementById("your_id").currentStyle["backgroundColor"]. La funzione rgb2hex()non è necessaria. Ecco il plugin jQuery che utilizza CSS Hooks che ho suggerito sopra, che fa già tutte le convalide per recuperare i colori in diversi browser: stackoverflow.com/questions/6177454/…
Erick Petrucelli

2
@Ghigo, penso che tu fraintenda: NON DOVREI utilizzare questa funzione se ti trovi in ​​un browser che ritorna in HEX. Questa funzione converte RGB in HEX e basta. Non usarlo quando non è in RGB. Il fatto che sia necessaria una soluzione più completa (che rilevi se il valore è già RGB, come realizzato da @ Jim-F) non modifica il fatto che questa soluzione offre esattamente ciò che è stato richiesto dall'OP. Il tuo downvote non ha senso, scusa.
Erick Petrucelli,

4
Mi dispiace ma non sono d'accordo. Una funzione cross browser è sempre migliore di una che necessita di esecuzione in base al rilevamento del browser. Op ha chiesto di convertire $('#selector').css('backgroundColor')in esadecimale, non un valore rgb in esadecimale. E su IE8, $('#selector').css('backgroundColor')è già esadecimale, quindi deve essere gestito. Questo è tutto. Non arrabbiarti con me :)
Ghigo,

1
Fallo ragazzi, una semplice fodera che ho aggiunto alla rgb2hex()funzione, grazie @ErickPetru! Devo codificare su IE7 che ci crediate o no. Con .css('backgroundColor')e obj.style.backgroundColorIE7 nativo e 8 restituiranno hex, non RGB, quindi ho aggiunto questa come prima riga nella rgb2hex()funzione nella risposta fornita in modo che funzioni fino a 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 # symbolSpero che sia d'aiuto.
gfrobenius,

61

La maggior parte dei browser sembra restituire il valore RGB quando si utilizza:

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

Solo IE (solo 6 testati finora) restituisce il valore esadecimale.

Per evitare messaggi di errore in IE, è possibile racchiudere la funzione in un'istruzione 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
Questo funziona meglio della maggior parte degli altri, poiché Jim tiene conto di rgba, che è ciò che Safari (almeno su Mac OS X) utilizza. Grazie Jim!
Pascal Lindelauf,

1
Ottima soluzione Notare che la funzione restituisce lettere minuscole, ad es. # Ff5544 non # FF5544.
Peter,

Questo regex supporterà anche i canali aplha nella soluzione precedente rgb = rgb.match (/ ^ rgba? ((\ D +), \ s * (\ d +), \ s * (\ d +) (?:, \ S * (0 \ \ d +.))) $ /);
Henning Winter,

lavorare come un incantesimo
ucMedia

22

@ErickPetru aggiornato per la compatibilità di 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]);
}

Ho aggiornato regex in modo che corrisponda al valore alfa, se definito, ma non lo uso.


Solo per completezza: sto lavorando a qualcosa che verrà esportato in PowerPoint (non chiedere ...) e accetta un quarto byte sulla stringa esadecimale per il canale alfa, quindi è possibile utilizzarlo in questo modo: 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)) : ''); Inoltre sto rimuovendo il #simbolo per renderlo agnostico dell'uso finale (si potrebbe ottenere l'output e anteporre 0xad esempio, o lasciarlo senza prefisso). Spero che aiuti qualcuno!
Óscar Gómez Alcañiz,

10

Ecco un ES6 one liner che non usa 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
Grazie, questo mi ha aiutato a incorporarlo in una pagina di Wordpress che rimuove le barre rovesciate delle regex nelle risposte precedenti.
Jason,

5

Ecco una versione che controlla anche la trasparenza, ne avevo bisogno poiché il mio oggetto era inserire il risultato in un attributo di stile, dove la versione trasparente di un colore esadecimale è in realtà la parola "trasparente".

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

Funzione che restituisce il colore di sfondo di un elemento in esadecimale.

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

esempio di utilizzo:

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

jsfiddle


4

Stessa risposta della risposta @Jim F ma sintassi ES6 , quindi meno istruzioni:

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 di colore prelevata dal selettore colore 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
        };
    }
};

come usare

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

3

Leggibile && Reg-exp gratuito (no Reg-exp)

Ho creato una funzione che utilizza funzioni di base leggibili e senza reg-exps.
La funzione accetta il colore in formato esadecimale, rgb o rgba CSS e restituisce una rappresentazione esadecimale.
EDIT: c'era un bug con l'analisi del formato rgba (), risolto ...

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
Non funziona su rgba (0,0,0,0). Primo: l'ordine deve cambiare .replace("rgba", "") .replace("rgb", "") .replace("(", "") .replace(")", "");Altrimenti, ti rimane con a0,0,0,0. E restituisce # 000000, che è Nero, anziché trasparente.
Dodici24,

Se il 4o valore in un rgba è 0 (zero), allora per css per quell''elemento 'sarebbe: element {color: # 000000, opacità: 0.0;} che è trasparente o restituisce semplicemente' rgba (0,0 , 0,0) 'torna al chiamante.
Dodici24,

@ Twelve24 Parsing fixed - In realtà ho notato che prima di leggere il tuo commento, ma sicuramente grazie per quello :), Per quanto riguarda la trasparenza - la funzione dovrebbe restituire il colore HEXA, o il "colore di base" - in modo che uno sia apposta :)
jave.web,

3

Provare

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

Questo sembra un po 'più bello:

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 più succinto:

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

forzando jQuery a restituire sempre 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

Solo per aggiungere alla risposta @ Justin sopra ..

dovrebbe essere

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

Poiché le funzioni di analisi di cui sopra tronca gli zeri iniziali, quindi produce codici colore errati di 5 o 4 lettere che possono essere ... vale a dire per rgb (216, 160, 10) produce # d8a0a mentre dovrebbe essere # d8a00a.

Grazie


1

Ecco una soluzione che ho scoperto che non genera errori di scripting in Internet Explorer: http://haacked.com/archive/2009/12/29/convert-rgb-to-hex.aspx


Nelle versioni precedenti di IE, recuperare un valore di colore di un oggetto usando jquery può talvolta restituire hex invece di rgb, mentre la maggior parte dei browser moderni restituisce RGB. Il collegamento alla funzione gestisce entrambi i casi d'uso
Paul T

1

La risposta di Steven Pribilinskiy rilascia zero iniziali, ad esempio # ff0000 diventa # ff00.

Una soluzione è quella di aggiungere uno 0 iniziale e sottostringa dalle ultime 2 cifre.

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

Poiché la domanda utilizzava JQuery, ecco un plug-in JQuery basato sul codice di 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));
};

Usalo come:

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

0

Ecco la mia soluzione, inoltre, supporta l'utilizzo di un argomento e controlla altri possibili spazi bianchi e maiuscole nella stringa fornita.

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

Su jsfiddle

Confronto della velocità su jsperf

Un ulteriore miglioramento potrebbe essere trim()la rgbstringa

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

0

La mia bella soluzione non standard

HTML

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

jQuery

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

Risultato

#f5b405

1
Restituisce tutto nello stile. : c
Eddie,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.