简体   繁体   English

如何获取十六进制颜色值而不是 RGB 值?

[英]How to get hex color value rather than RGB value?

Using the following jQuery will get the RGB value of an element's background color:使用以下 jQuery 将获取元素背景颜色的 RGB 值:

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

Is there a way to get the hex value rather than the RGB?有没有办法获取十六进制值而不是 RGB?

TLDR TLDR

Use this clean one-line function with both rgb and rgba support:使用这个干净的单行函数同时支持rgbrgba

const rgba2hex = (rgba) => `#${rgba.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+\.{0,1}\d*))?\)$/).slice(1).map((n, i) => (i === 3 ? Math.round(parseFloat(n) * 255) : parseFloat(n)).toString(16).padStart(2, '0').replace('NaN', '')).join('')}`

2021 updated answer 2021 更新答案

Much time has passed since I originally answered this question.自从我最初回答这个问题以来已经过去了很长时间。 Then cool ECMAScript 5 and 2015+ features become largely available on browsers, like arrow functions , Array.map , String.padStart and template strings .然后很酷的 ECMAScript 5 和 2015+ 特性在浏览器上大量可用,如箭头函数Array.mapString.padStart模板字符串 So now it's possible to write an one-liner rgb2hex :所以现在可以编写一个单行rgb2hex

 const rgb2hex = (rgb) => `#${rgb.match(/^rgb\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)$/).slice(1).map(n => parseInt(n, 10).toString(16).padStart(2, '0')).join('')}` // Use as you wish... console.log(rgb2hex('rgb(0,0,0)')) console.log(rgb2hex('rgb(255, 255, 255)')) console.log(rgb2hex('rgb(255,0,0)')) console.log(rgb2hex('rgb(38, 170, 90)'))

Basically, we use a regular expression to get each digit inside the rgb string, slice(1) to get only the digits (the first result of match is the full string itself), map to iterate through each digit, each iteration converting to Number with parseInt , then back to an hexadecimal String (through a base-16 conversion), adding zero if needed via padStart .基本上,我们使用正则表达式获取rgb字符串中的每个数字, slice(1)仅获取数字( match的第一个结果是完整字符串本身), map以遍历每个数字,每次迭代转换为Number使用parseInt ,然后返回一个十六进制String (通过 base-16 转换),如果需要通过padStart添加零。 Finally, just join each converted/adjusted digit to a unique String starting with '#' .最后,只需join每个转换/调整后的数字连接到一个以'#'开头的唯一String

Of course, we could extend it without much effort as an one-liner rgba2hex :当然,我们可以毫不费力地将它扩展为单行rgba2hex

 const rgba2hex = (rgba) => `#${rgba.match(/^rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*(\\d+\\.{0,1}\\d*))?\\)$/).slice(1).map((n, i) => (i === 3 ? Math.round(parseFloat(n) * 255) : parseFloat(n)).toString(16).padStart(2, '0').replace('NaN', '')).join('')}` // Now it doesn't matter if 'rgb' or 'rgba'... console.log(rgba2hex('rgb(0,0,0)')) console.log(rgba2hex('rgb(255, 255, 255)')) console.log(rgba2hex('rgb(255,0,0)')) console.log(rgba2hex('rgb(38, 170, 90)')) console.log(rgba2hex('rgba(255, 0, 0, 0.5)')) console.log(rgba2hex('rgba(0,255,0,1)')) console.log(rgba2hex('rgba(127,127,127,0.25)'))

And that's it.就是这样。 But if you want to dive deep in the old school JavaScript world, keep reading.但是,如果您想深入了解旧式 JavaScript 世界,请继续阅读。


Original 2010 answer 2010 年的原始答案

Here is the cleaner solution I wrote based on @Matt 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]);
}

Some browsers already returns colors as hexadecimal (as of Internet Explorer 8 and below).某些浏览器已将颜色返回为十六进制(从 Internet Explorer 8 及以下版本开始)。 If you need to deal with those cases, just append a condition inside the function, like @gfrobenius suggested:如果您需要处理这些情况,只需在函数内附加一个条件,就像@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]);
}

If you're using jQuery and want a more complete approach, you can use CSS Hooks available since jQuery 1.4.3, as I showed when answering this question: Can I force jQuery.css("backgroundColor") returns on hexadecimal format?如果您正在使用 jQuery 并想要更完整的方法,您可以使用自 jQuery 1.4.3 以来可用的CSS Hooks ,正如我在回答这个问题时所展示的: Can I force jQuery.css("backgroundColor") returns on hexadecimal format?

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 ) 来源

Most browsers seem to return the RGB value when using:大多数浏览器在使用时似乎会返回 RGB 值:

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

Only IE (only 6 tested so far) returns the Hex value.只有 IE(到目前为止只测试了 6 个)返回十六进制值。

To avoid error messages in IE, you could wrap the function in an if statement:为了避免 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]); 
     }
}

Updated @ErickPetru for rgba compatibility:更新了@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]);
}

I updated the regex to match the alpha value if defined, but not use it.如果定义了,我更新了正则表达式以匹配 alpha 值,但不使用它。

Here's an ES6 one liner that doesn't use jQuery:这是一个不使用 jQuery 的 ES6 one liner:

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

Here is a version that also checks for transparent, I needed this since my object was to insert the result into a style attribute, where the transparent version of a hex color is actually the word "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]); 
     }
}

Function that returns background color of an element in hex.以十六进制返回元素背景颜色的函数。

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

usage example:用法示例:

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

jsfiddle提琴手

Same answer like @Jim F answer but ES6 syntax , so, less instructions :@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]);
};

Try尝试

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

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

color class taken from bootstrap color picker从引导颜色选择器中获取的颜色类

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

how to use如何使用

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

Readable && Reg-exp free (no Reg-exp) Readable && Reg-exp free (no Reg-exp)

I've created a function that uses readable basic functions and no reg-exps.我创建了一个函数,它使用可读的基本函数并且没有正则表达式。
The function accepts color in hex, rgb or rgba CSS format and returns hex representation.该函数接受十六进制、rgb或 rgba CSS 格式的颜色并返回十六进制表示。
EDIT: there was a bug with parsing out rgba() format, fixed...编辑:解析 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);
}

Just to add to @Justin's answer above..只是为了添加到@Justin上面的答案..

it should be它应该是

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

As the above parse int functions truncates leading zeroes, thus produces incorrect color codes of 5 or 4 letters may be... ie for rgb(216, 160, 10) it produces #d8a0a while it should be #d8a00a.由于上述解析 int 函数会截断前导零,因此产生 5 或 4 个字母的错误颜色代码可能是...即对于 rgb(216, 160, 10) 它产生 #d8a0a 而它应该是 #d8a00a。

Thanks谢谢

This one looks a bit nicer:这个看起来好一点:

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

a more succinct one-liner:更简洁的单行:

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

forcing jQuery to always return hex:强制 jQuery 总是返回十六进制:

$.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's answer drops leading zeroes, for example #ff0000 becomes #ff00. Steven Pribilinskiy 的回答去掉了前导零,例如#ff0000 变为#ff00。

A solution is to append a leading 0 and substring off the last 2 digits.一种解决方案是在最后 2 位数字后附加前导 0 和子字符串。

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

Since the question was using JQuery, here's a JQuery plugin based on Daniel Elliott's code:由于问题是使用 JQuery,这里有一个基于 Daniel Elliott 代码的 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));
};

Use it like:像这样使用它:

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

这是我发现不会在 IE 中引发脚本错误的解决方案: http : //haacked.com/archive/2009/12/29/convert-rgb-to-hex.aspx

Improved function "hex"改进的功能“十六进制”

function hex(x){
    return isNaN(x) ? "00" : hexDigits[x >> 4] + hexDigits[x & 0xf];
    // or option without hexDigits array
    return (x >> 4).toString(16)+(x & 0xf).toString(16);
}

Here is my solution, also does touppercase by the use of an argument and checks for other possible white-spaces and capitalisation in the supplied string.这里是我的解决方案,也不会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));

On jsfiddlejsfiddle 上

Speed comparison on jsperf jsperf 上的速度比较

A further improvement could be to trim() the rgb string进一步的改进可能是trim() rgb字符串

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

My beautiful non-standard solution我美丽的非标解决方案

HTML HTML

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

jQuery jQuery

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

Result结果

#f5b405

Convert RGB to Hex将 RGB 转换为十六进制

I am using Jasmine protractor and I was getting errors like - Expected [ 'rgba(255, 255, 255, 1)' ] to contain '#fff'.我正在使用 Jasmine 量角器,但出现错误,例如- Expected [ 'rgba(255, 255, 255, 1)' ] to contain '#fff'. Below function worked fine for me.下面的功能对我来说很好用。

function RGBAToHexA(test:string) {
let sep = test.toString().indexOf(",") > -1 ? "," : " ";
const rgba = test.toString().substring(5).split(")")[0].split(sep);
console.log(rgba)
let r = (+rgba[0]).toString(16),
  g = (+rgba[1]).toString(16),
  b = (+rgba[2]).toString(16),
  a = Math.round(+rgba[3] * 255).toString(16);

    if (r.length == 1)
        r = "0" + r;
    if (g.length == 1)
        g = "0" + g;
    if (b.length == 1)
        b = "0" + b;
    if (a.length == 1)
        a = "0" + a;

return "#" + r + g + b + a;

} }

describe('Check CSS', function() {
 
it('should check css of login page', async function(){
        browser.waitForAngularEnabled(true);
        browser.actions().mouseMove(element(by.css('.btn-auth, .btn-auth:hover'))).perform(); // mouse hover on button
        csspage.Loc_auth_btn.getCssValue('color').then(function(color){
            console.log(RGBAToHexA(color))
            expect( RGBAToHexA(color)).toContain(cssData.hoverauth.color);

        })

       

To all the Functional Programming lovers, here is a somewhat functional approach :)对于所有函数式编程爱好者,这里有一个有点函数式的方法:)

const getHexColor = (rgbValue) =>
  rgbValue.replace("rgb(", "").replace(")", "").split(",")
    .map(colorValue => (colorValue > 15 ? "0" : "") + colorValue.toString(16))
    .reduce((acc, hexValue) => acc + hexValue, "#")

then use it like:然后像这样使用它:

const testRGB = "rgb(13,23,12)"
getHexColor(testRGB)

my compact version我的精简版

 //Function to convert rgb color to hex format function rgb2hex(rgb) { if(/^#/.test(rgb))return rgb;// if returns colors as hexadecimal let re = /\\d+/g; let hex = x => (x >> 4).toString(16)+(x & 0xf).toString(16); return "#"+hex(re.exec(rgb))+hex(re.exec(rgb))+hex(re.exec(rgb)); }

full cases (rgb, rgba, transparent...etc) solution (coffeeScript)完整案例(rgb、rgba、透明...等)解决方案(coffeeScript)

 rgb2hex: (rgb, transparentDefault=null)->
    return null unless rgb
    return rgb if rgb.indexOf('#') != -1
    return transparentDefault || 'transparent' if rgb == 'rgba(0, 0, 0, 0)'
    rgb = rgb.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+))?\)$/);
    hex = (x)->
      ("0" + parseInt(x).toString(16)).slice(-2)

    '#' + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3])

Hi here's my solution after getting the element's color with Javascript您好,这是我使用 Javascript 获取元素颜色后的解决方案

function rgb_hex(rgb_string_js){ //example: "rgb(102,54,255)"
  var new_rgb_list = rgb_string_js.replace("rgb(","").replace(")","").split(",");
  return ("#" + parseInt(new_rgb_list[0]).toString(16) + parseInt(new_rgb_list[1]).toString(16) + parseInt(new_rgb_list[2]).toString(16)); 
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM