Wie erhalte ich einen Hex-Farbwert anstelle eines RGB-Werts?

171

Mit der folgenden jQuery wird der RGB-Wert der Hintergrundfarbe eines Elements ermittelt:

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

Gibt es eine Möglichkeit, den Hex-Wert anstelle des RGB zu erhalten?

bfavaretto
quelle
2
Zu einem verwandten Thema gibt es hier mehr (und wahrscheinlich bessere) Möglichkeiten zum Konvertieren zwischen Hex- und RGB-Farben: stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb Dieses Rad wurde oft genug neu erfunden einen Straßenzug bauen. Ich hatte gehofft, dass eine der beliebten JS-Bibliotheken, einfacher als weniger, eine Utility-Funktion haben würde.
Michael Scheper
Denken Sie daran, dass einige Browser rgba (#, #, #, #) zurückgeben, z. B. rgba (0,0,0,0), das transparent und nicht schwarz ist. Der 4. Wert ist die Deckkraft, wobei 1,0 100% Vollfarbe und 0,5 50% ist.
Twelve24

Antworten:

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

( Quelle )

Daniel Elliott
quelle
7
+1, Sie könnten Number.toString (16) verwenden - zumindest für jede hexadezimale Ziffer (oder Pad mit 0, wenn unter 16)
orip
19
-1. Wie von orip erwähnt, können Sie toString (16) verwenden. Für andere Ineffizienzen herabgestimmt. Wenn Sie hexDigits bei jedem Funktionsaufruf deklarieren möchten, tun Sie dies zumindest im Funktionskörper von rgb2hex (nicht im Körper von hex), damit das Array nicht dreimal pro 1 Aufruf von rgb2hex neu definiert wird. Lernen Sie auch, 'var' zu verwenden, damit Sie den globalen Bereich nicht verschmutzen.
Matt
3
Diese Methode scheint nicht sehr tolerant gegenüber unterschiedlichen Leerzeichen oder Großschreibungen zu sein. jsfiddle.net/Xotic750/pSQ7d
Xotic750
1
Wenn Sie wirklich pedantisch sein möchten, können Sie den regulären Ausdruck toleranter gestalten: rgb.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i)Der angegebene reguläre Ausdruck ist jedoch so konzipiert, dass er mit dem Format übereinstimmt, das ein Browser bei Verwendung von jQuery angibt, und dies hat keine unterschiedlichen Leerraum- oder Captilisierungskonsistenzen du redest über. Sie können auch denselben regulären Ausdruck verwenden und einfach alle Leerzeichen entfernen und in Kleinbuchstaben konvertieren, bevor Sie mit rgb übereinstimmen. PS Ihr Geigenbeispiel: 'rgb (10, 128,)' Ich denke nicht, dass es vernünftig ist, am
binderbound
und für mich kommt die rückgabe von jquery css hintergrundfarben im format mit rgba, also funktioniert das nicht.
Miguel
159

Hier ist die sauberere Lösung, die ich basierend auf dem @ Matt-Vorschlag geschrieben habe:

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

Einige Browser geben Farben bereits hexadezimal zurück (ab Internet Explorer 8 und niedriger). Wenn Sie sich mit diesen Fällen befassen müssen, fügen Sie einfach eine Bedingung in die Funktion ein, wie von @gfrobenius vorgeschlagen:

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

Wenn Sie jQuery verwenden und einen vollständigeren Ansatz wünschen, können Sie CSS-Hooks verwenden, die seit jQuery 1.4.3 verfügbar sind, wie ich bei der Beantwortung dieser Frage gezeigt habe: Kann ich die Rückgabe von jQuery.css ("backgroundColor") im hexadezimalen Format erzwingen?

Erick Petrucelli
quelle
2
Ich empfehle allen: Sehen Sie sich meine Antwort hier an, um eine verbesserte Version mit jQuery CSS Hooks zu sehen .
Erick Petrucelli
1
@ Ghigo, sorry aber du liegst falsch. IE8 bereits gibt Farben als hexadezimale , wenn Sie den aktuellen Stil bekommen, auf diese Weise: document.getElementById("your_id").currentStyle["backgroundColor"]. Die Funktion rgb2hex()wird nicht benötigt. Hier ist das oben vorgeschlagene jQuery-Plugin mit CSS-Hooks, das bereits alle Überprüfungen durchführt, um Farben in verschiedenen Browsern wiederherzustellen
Erick Petrucelli
2
@ Ghigo, ich denke du missverstehst: du solltest diese Funktion NICHT verwenden, wenn du in einem Browser bist, der in HEX zurückkehrt. Diese Funktion konvertiert RGB in HEX und genau das. Verwenden Sie es nicht, wenn es nicht in RGB ist. Die Tatsache, dass Sie eine vollständigere Lösung benötigen (die erkennt, ob der Wert bereits RGB ist, wie von @ Jim-F erstellt), ändert nichts an der Tatsache, dass diese Lösung genau das bietet, was vom OP angefordert wurde. Ihre Ablehnung macht leider keinen Sinn.
Erick Petrucelli
4
Es tut mir leid, aber ich stimme nicht zu. Eine browserübergreifende Funktion ist immer besser als eine, die basierend auf der Browsererkennung ausgeführt werden muss. Op wurde gebeten, $('#selector').css('backgroundColor')in hex umzuwandeln , nicht in einen RGB-Wert in hex. Und auf IE8 $('#selector').css('backgroundColor')ist bereits hex, so dass es behandelt werden muss. Das ist es. Sei nicht böse auf mich :)
Ghigo
1
Mach das, ein einfacher rgb2hex()Einzeiler , den ich der Funktion hinzugefügt habe , danke @ErickPetru! Ich muss zurück zu IE7 codieren, ob Sie es glauben oder nicht. Mit .css('backgroundColor')und native obj.style.backgroundColorIE7 & 8 wird hexadezimal zurückgegeben, nicht RGB. Daher habe ich dies als erste Zeile in der rgb2hex()Funktion in der angegebenen Antwort hinzugefügt , damit es bis zurück zu IE7 funktioniert: /* 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 # symbolHoffe, das hilft.
Gfrobenius
60

Die meisten Browser scheinen den RGB-Wert zurückzugeben, wenn sie Folgendes verwenden:

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

Nur IE (bisher nur 6 getestet) gibt den Hex-Wert zurück.

Um Fehlermeldungen im IE zu vermeiden, können Sie die Funktion in eine if-Anweisung einschließen:

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]); 
     }
}
Jim F.
quelle
1
Dieser funktioniert besser als die meisten anderen, da Jim rgba berücksichtigt, was Safari (zumindest unter Mac OS X) verwendet. Danke, Jim!
Pascal Lindelauf
1
Tolle Lösung. Beachten Sie, dass die Funktion Kleinbuchstaben zurückgibt, dh # ff5544, nicht # FF5544.
Peter
Dieser Regex unterstützt auch Aplha-Kanäle in der obigen Lösung. Rgb = rgb.match (/ ^ rgba? ((\ D +), \ s * (\ d +), \ s * (\ d +) (?:, \ S *) (0 \. \ D +))?) $ /);
Henning Winter
arbeite wie ein Zauber
ucMedia
22

@ErickPetru wurde aus Gründen der RGBA-Kompatibilität aktualisiert:

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

Ich habe die Regex so aktualisiert, dass sie mit dem Alpha-Wert übereinstimmt, falls definiert, aber nicht verwendet.

Zack Katz
quelle
Der Vollständigkeit halber: Ich arbeite an einer Sache, die nach PowerPoint exportiert wird (fragen Sie nicht ...), und sie akzeptiert ein viertes Byte in der Hex-Zeichenfolge für den Alphakanal, sodass man sie folgendermaßen verwenden kann: 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)) : ''); Außerdem entferne ich das #Symbol, um es für die endgültige Verwendung agnostisch zu machen (man könnte die Ausgabe abrufen und sie 0xbeispielsweise voranstellen oder sie ohne Präfix belassen). Hoffe es hilft jemandem!
Óscar Gómez Alcañiz
10

Hier ist ein ES6-Einzeiler, der jQuery nicht verwendet:

var rgb = document.querySelector('#selector').style['background-color'];
return '#' + rgb.substr(4, rgb.indexOf(')') - 4).split(',').map((color) => parseInt(color).toString(16)).join('');
Justin McCandless
quelle
1
Vielen Dank, das hat mir geholfen, es in eine Wordpress-Seite zu integrieren, die die Regex-Backslashes in den vorherigen Antworten entfernt.
Jason
5

Hier ist eine Version, die auch nach Transparenz sucht. Ich brauchte diese, da mein Ziel darin bestand, das Ergebnis in ein Stilattribut einzufügen, wobei die transparente Version einer Hex-Farbe tatsächlich das Wort "transparent" ist.

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]); 
     }
}
Matt Welander
quelle
4

Funktion, die die Hintergrundfarbe eines Elements in hex zurückgibt.

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

Anwendungsbeispiel:

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

jsfiddle

shaik
quelle
4

Gleiche Antwort wie @ Jim F-Antwort, aber ES6- Syntax, also weniger Anweisungen:

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]);
};
Abdennour TOUMI
quelle
3

Farbklasse aus dem Bootstrap-Farbwähler

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

wie benutzt man

var color = new Color("RGB(0,5,5)");
color.toHex()
Fareed Alnamrouti
quelle
3

Lesbar && Reg-exp kostenlos (kein Reg-exp)

Ich habe eine Funktion erstellt, die lesbare Grundfunktionen und keine reg-exps verwendet.
Die Funktion akzeptiert Farben im CSS-Format hex, rgb oder rgba und gibt die hexadezimale Darstellung zurück.
EDIT: Es gab einen Fehler beim Parsen des rgba () -Formats, behoben ...

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
quelle
1
Funktioniert nicht mit rgba (0,0,0,0). Erstens: Die Reihenfolge muss sich ändern. .replace("rgba", "") .replace("rgb", "") .replace("(", "") .replace(")", "");Andernfalls bleibt a0,0,0,0 übrig. Und es gibt # 000000 zurück, was Schwarz ist, anstatt transparent.
Twelve24
Wenn der 4. Wert in einem RGBA 0 (Null) ist, wäre für CSS für dieses 'Element': Element {Farbe: # 000000, Deckkraft: 0.0;}, das transparent ist oder nur bedingt das 'RGBA (0,0) zurückgibt , 0,0) 'zurück zum Anrufer.
Twelve24
@ Twelve24 Parsing behoben - Ich habe das tatsächlich bemerkt, bevor ich Ihren Kommentar gelesen habe, aber auf jeden Fall danke dafür :), Was die Transparenz betrifft - die Funktion soll HEXA-Farbe oder die "Grundfarbe" zurückgeben - damit eine absichtlich ist :)
jave.web
3

Versuchen

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

Kamil Kiełczewski
quelle
2

Dieser sieht ein bisschen schöner aus:

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

ein prägnanter Einzeiler:

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

Erzwingen, dass jQuery immer hex zurückgibt:

$.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]);
        }
    }
}
Steven Pribilinskiy
quelle
2

Nur um @ Justins Antwort oben hinzuzufügen ..

es sollte sein

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

Da die obige Analyse int-Funktionen führende Nullen abschneidet, können falsche Farbcodes mit 5 oder 4 Buchstaben erzeugt werden ... dh für rgb (216, 160, 10) wird # d8a0a erzeugt, während es # d8a00a sein sollte.

Vielen Dank

Yogesh Kumar Gupta
quelle
1

Ich habe eine Lösung gefunden, die keine Skriptfehler im IE auslöst: http://haacked.com/archive/2009/12/29/convert-rgb-to-hex.aspx

Mike
quelle
In älteren IE-Versionen kann das Abrufen eines Farbwerts eines Objekts mithilfe von jquery manchmal hex anstelle von rgb zurückgeben, während die meisten modernen Browser RGB zurückgeben. Die mit verknüpfte Funktion behandelt beide Anwendungsfälle
Paul T
1

Die Antwort von Steven Pribilinskiy lässt führende Nullen fallen, zum Beispiel wird # ff0000 zu # ff00.

Eine Lösung besteht darin, eine führende 0 anzuhängen und die letzten 2 Ziffern mit einem Teilstring zu versehen.

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
quelle
1

Da die Frage JQuery verwendete, ist hier ein JQuery-Plugin, das auf Daniel Elliotts Code basiert:

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

Verwenden Sie es wie:

var hexBackgroundColor = $('#myElement').cssAsHex('background-color');
Tom Söderlund
quelle
0

Hier ist meine Lösung, macht auch Großbuchstaben durch die Verwendung eines Arguments und prüft auf andere mögliche Leerzeichen und Großschreibung in der angegebenen Zeichenfolge.

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

Auf jsfiddle

Geschwindigkeitsvergleich auf jsperf

Eine weitere Verbesserung könnte trim()die rgbSaite sein

var rxArray = rgb.trim().match(rx),
Xotic750
quelle
0

Meine schöne nicht standardmäßige Lösung

HTML

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

jQuery

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

Ergebnis

#f5b405
Newred
quelle
1
Es gibt alles im Stil zurück. : c
Eddie