Làm thế nào để có được giá trị màu hex chứ không phải giá trị RGB?


171

Sử dụng jQuery sau đây sẽ nhận được giá trị RGB của màu nền của phần tử:

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

Có cách nào để có được giá trị hex hơn là RGB không?


2
Về một chủ đề liên quan, nhiều cách (và có thể nói là tốt hơn) để chuyển đổi giữa các màu hex và RGB có tại đây: stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb Bánh xe này đã được phát minh lại đủ lần để xây dựng một con đường xe lửa. Tôi đã hy vọng một trong những thư viện JS phổ biến, đơn giản hơn ít hơn, sẽ có chức năng tiện ích.
Michael Scheper

Hãy nhớ rằng một số trình duyệt trả về rgba (#, #, #, #), chẳng hạn như rgba (0,0,0,0) trong suốt, không phải màu đen. Giá trị thứ 4 là độ mờ đục, với 1.0 là màu đầy đủ 100% và 0,5 là 50%.
Mười hai24

Câu trả lời:


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

( Nguồn )


7
+1, Bạn có thể sử dụng Number.toString (16) - ít nhất là cho mỗi chữ số hex (hoặc pad có 0 nếu dưới 16)
orip

19
-1. Như được đề cập bởi orip, bạn có thể sử dụng toString (16). Downvote cho sự không hiệu quả khác. Nếu bạn định khai báo hexDigits trên mỗi lệnh gọi hàm, ít nhất hãy thực hiện nó trong thân hàm của rgb2hex (không phải thân hex), vì vậy mảng không được xác định lại 3 lần trên 1 cuộc gọi đến rgb2hex. Ngoài ra, hãy học cách sử dụng 'var', vì vậy bạn không gây ô nhiễm phạm vi toàn cầu.
Matt

3
Phương pháp này dường như không khoan dung cho việc sử dụng khoảng trắng hoặc viết hoa khác nhau. jsfiddle.net/Xotic750/pSQ7d
Xotic750

1
Nếu bạn thực sự muốn trở thành nhà mô phạm, bạn có thể làm cho biểu thức chính dễ dàng hơn: rgb.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i)Tuy nhiên, biểu thức chính được đưa ra được thiết kế để đối phó với định dạng do trình duyệt đưa ra khi sử dụng jQuery và điều này không có tính nhất quán của không gian trắng hoặc lưu giữ bạn đang nói về. Bạn cũng có thể sử dụng regex tương tự và chỉ cần loại bỏ tất cả các khoảng trắng và chuyển đổi thành chữ thường trước khi khớp trên rgb. PS Ví dụ thú vị của bạn: 'rgb (10, 128,)' Tôi không nghĩ rằng điều đó là hợp lý để thử nghiệm
binderbound

và đối với tôi, sự trở lại của màu nền jquery css có định dạng với rgba, vì vậy điều này không hoạt động.
Miguel

159

Đây là giải pháp sạch hơn tôi đã viết dựa trên đề xuất @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]);
}

Một số trình duyệt đã trả về màu dưới dạng thập lục phân (kể từ Internet Explorer 8 trở xuống). Nếu bạn cần xử lý những trường hợp đó, chỉ cần thêm một điều kiện bên trong hàm, như @gfrobenius đề xuất:

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

Nếu bạn đang sử dụng jQuery và muốn một cách tiếp cận đầy đủ hơn, bạn có thể sử dụng CSS Hook có sẵn kể từ jQuery 1.4.3, như tôi đã trình bày khi trả lời câu hỏi này: Tôi có thể buộc jQuery.css ("backgroundColor") trả về định dạng thập lục phân không?


2
Tôi đề nghị với mọi người: hãy xem phản hồi của tôi ở đây để xem phiên bản cải tiến bằng cách sử dụng jQuery CSS Hook .
Erick Petrucelli

1
@Ghigo, xin lỗi nhưng bạn sai rồi. IE8 đã trả về màu sắc dưới dạng thập lục phân khi lấy kiểu hiện tại, theo cách này : document.getElementById("your_id").currentStyle["backgroundColor"]. Các chức năng rgb2hex()không cần thiết. Đây là plugin jQuery sử dụng CSS Hook mà tôi đã đề xuất ở trên, đã thực hiện tất cả các xác thực để khôi phục màu trong các trình duyệt khác nhau: stackoverflow.com/questions/6177454/
Lỗi

2
@Ghigo, tôi nghĩ bạn hiểu nhầm: bạn KHÔNG NÊN sử dụng chức năng này nếu bạn đang ở trong trình duyệt trả về HEX. Hàm này chuyển đổi RGB thành HEX và chỉ nó. Không sử dụng nó khi nó không có trong RGB. Thực tế là bạn cần một giải pháp hoàn chỉnh hơn (phát hiện nếu giá trị đã là RGB, như được tạo bởi @ Jim-F) không thay đổi thực tế rằng giải pháp này cung cấp chính xác những gì được OP yêu cầu. Downvote của bạn không có ý nghĩa, xin lỗi.
Erick Petrucelli

4
Tôi xin lỗi nhưng tôi không đồng ý. Một chức năng trình duyệt chéo luôn tốt hơn chức năng cần thực thi dựa trên phát hiện trình duyệt. Op yêu cầu chuyển đổi $('#selector').css('backgroundColor')sang hex, không phải giá trị rgb thành hex. Và trên IE8, $('#selector').css('backgroundColor')đã là hex nên nó phải được xử lý. Đó là nó. Đừng giận tôi :)
Ghigo 28/03/13

1
Làm điều này, một lớp lót đơn giản tôi đã thêm vào rgb2hex()chức năng, cảm ơn @ErickPetru! Tôi phải mã lại cho IE7 tin hay không. Với IE7 & 8 .css('backgroundColor')bản địa obj.style.backgroundColorsẽ trả về hex, không phải RGB, vì vậy tôi đã thêm đây là dòng đầu tiên trong rgb2hex()hàm trong câu trả lời được cung cấp để nó hoạt động hoàn toàn trở lại 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 # symbolHy vọng điều đó có ích.
gfrobenius

61

Hầu hết các trình duyệt dường như trả về giá trị RGB khi sử dụng:

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

Chỉ IE (chỉ có 6 thử nghiệm cho đến nay) trả về giá trị Hex.

Để tránh các thông báo lỗi trong IE, bạn có thể gói hàm trong câu lệnh 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
Cái này hoạt động tốt hơn hầu hết những cái khác, vì Jim đưa rgba vào tài khoản, đó là thứ mà Safari (ít nhất là trên Mac OS X) sử dụng. Cảm ơn, Jim!
Pascal Lindelauf

1
Giải pháp tuyệt vời. Lưu ý rằng hàm trả về các chữ cái viết thường, tức là # ff5544 chứ không phải # FF5544.
Peter

Regex này sẽ hỗ trợ các kênh aplha cũng như trong giải pháp trên rgb = rgb.match (/ ^ rgba? ((\ D +), \ s * (\ d +), \ s * (\ d +) (?:, \ S * (0 \. \ D +))?) $ /);
Henning Winter

làm việc như một cơ duyên
ucMedia

22

Đã cập nhật @ErickPetru để tương thích với 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]);
}

Tôi đã cập nhật regex để khớp với giá trị alpha nếu được xác định, nhưng không sử dụng nó.


Để hoàn thiện: Tôi đang nghiên cứu một thứ sẽ xuất sang PowerPoint (đừng hỏi ...) và nó chấp nhận một byte thứ tư trên chuỗi hex cho kênh alpha, vì vậy người ta có thể sử dụng nó như thế này: 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)) : ''); Ngoài ra, tôi đang xóa #biểu tượng để làm cho nó không rõ ràng về việc sử dụng cuối cùng (người ta có thể lấy đầu ra và 0xlấy ví dụ trước, hoặc để nó không có tiền tố). Hy vọng nó sẽ giúp được ai đó!
Óscar Gómez Alcañiz

10

Đây là một lớp lót ES6 không sử dụng 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
Cảm ơn, điều đó đã giúp tôi kết hợp nó vào một trang Wordpress để loại bỏ các dấu gạch chéo ngược trong các câu trả lời trước đó.
Jason

5

Đây là một phiên bản cũng kiểm tra độ trong suốt, tôi cần điều này vì đối tượng của tôi là chèn kết quả vào thuộc tính style, trong đó phiên bản trong suốt của màu hex thực sự là từ "trong suốt" ..

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

Hàm trả về màu nền của một phần tử trong 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;
}

ví dụ sử dụng:

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

jsfiddle


4

Câu trả lời giống như câu trả lời @Jim F nhưng cú pháp ES6 , vì vậy, ít hướng dẫn hơn:

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

lớp màu lấy từ bộ chọn màu 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
        };
    }
};

cách sử dụng

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

3

Có thể đọc && Reg-exp miễn phí (không có Reg-exp)

Tôi đã tạo một hàm sử dụng các hàm cơ bản có thể đọc được và không có reg-exp.
Hàm chấp nhận màu ở định dạng CSS hex, rgb hoặc rgba và trả về biểu diễn hex.
EDIT: đã xảy ra lỗi khi phân tích cú pháp định dạng rgba (), đã sửa ...

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
Không hoạt động trên rgba (0,0,0,0). Đầu tiên: thứ tự cần thay đổi .replace("rgba", "") .replace("rgb", "") .replace("(", "") .replace(")", "");Nếu không, bạn sẽ bị bỏ lại với a,0,0,0. Và, nó trả về # 000000, màu Đen, thay vì trong suốt.
Mười hai24

Nếu giá trị thứ 4 trong rgba là 0 (không), thì đối với css cho 'phần tử' đó sẽ là: phần tử {color: # 000000, opacity: 0.0;} trong suốt hoặc chỉ trả về điều kiện 'rgba (0,0 , 0,0) 'trở lại người gọi.
Mười hai24

@ Twelve24 Phân tích cú pháp cố định - Tôi thực sự nhận thấy rằng trước khi đọc bình luận của bạn, nhưng chắc chắn cảm ơn vì điều đó :), vì tính minh bạch - chức năng được cho là trả về màu HEXA, hoặc "màu cơ bản" - để một mục đích được sử dụng :)
jave.web

3

Thử

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

Cái này trông đẹp hơn một chút:

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

một lớp lót ngắn gọn hơn:

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

buộc jQuery luôn trả về 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

Chỉ cần thêm vào câu trả lời của @ Justin ở trên ..

nó nên

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

Vì các hàm phân tích int ở trên cắt bớt các số 0 đứng đầu, do đó tạo ra mã màu không chính xác gồm 5 hoặc 4 chữ cái có thể là ... tức là đối với rgb (216, 160, 10), nó tạo ra # d8a0a trong khi nó phải là # d8a00a.

Cảm ơn


1

Đây là một giải pháp tôi thấy rằng không gây ra lỗi script trong IE: http://haacked.com/archive/2009/12/29/convert-rgb-to-hex.aspx


Trong các phiên bản IE cũ hơn, việc tìm nạp giá trị màu của một đối tượng bằng jquery đôi khi có thể trả về hex thay vì rgb, trong khi hầu hết các trình duyệt hiện đại đều trả về RGB. Các liên kết đến chức năng xử lý cả hai trường hợp sử dụng
Paul T

1

Câu trả lời của Steven Pribilinskiy giảm các số 0 hàng đầu, ví dụ # ff0000 trở thành # ff00.

Một giải pháp là nối thêm 0 hàng đầu và chuỗi con ra khỏi 2 chữ số cuối.

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

Vì câu hỏi đang sử dụng JQuery, đây là một plugin JQuery dựa trên mã của 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));
};

Sử dụng nó như:

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

0

Đây là giải pháp của tôi, cũng như touppercase bằng cách sử dụng một đối số và kiểm tra các khoảng trắng và viết hoa có thể khác trong chuỗi được cung cấp.

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

Trên jsfiddle

So sánh tốc độ trên jsperf

Một cải tiến hơn nữa có thể là để trim()các rgbchuỗi

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

0

Giải pháp không chuẩn của tôi

HTML

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

jQuery

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

Kết quả

#f5b405

1
Nó trả về mọi thứ trong phong cách. : c
Eddie
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.