Bagaimana cara mendapatkan nilai warna hex daripada nilai RGB?


171

Menggunakan jQuery berikut ini akan mendapatkan nilai RGB warna latar elemen:

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

Apakah ada cara untuk mendapatkan nilai hex daripada RGB?


2
Pada topik terkait, lebih banyak (dan bisa dibilang lebih baik) cara untuk mengkonversi antara warna hex dan RGB ada di sini: stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb Roda ini telah diciptakan kembali cukup banyak kali untuk membangun kereta jalan. Saya berharap salah satu perpustakaan JS populer, lebih sederhana daripada kurang, akan memiliki fungsi utilitas.
Michael Scheper

Ingat bahwa beberapa browser mengembalikan rgba (#, #, #, #), seperti rgba (0,0,0,0) yang transparan, bukan hitam. Nilai 4 adalah opacity, dengan 1,0 menjadi penuh warna 100% dan 0,5 menjadi 50%.
Twelve24

Jawaban:


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

( Sumber )


7
+1, Anda dapat menggunakan Number.toString (16) - setidaknya untuk setiap digit hex (atau pad dengan 0 jika di bawah 16)
orip

19
-1. Seperti yang disebutkan oleh orip, Anda dapat menggunakan toString (16). Turun karena ketidakefisienan lainnya. Jika Anda akan mendeklarasikan hexDigits pada setiap panggilan fungsi, setidaknya lakukan di fungsi tubuh rgb2hex (bukan tubuh hex), sehingga array tidak didefinisikan ulang 3 kali per 1 panggilan ke rgb2hex. Juga belajar menggunakan 'var', sehingga Anda tidak mencemari ruang lingkup global.
Matt

3
Metode ini tampaknya tidak terlalu toleran terhadap perbedaan white-space atau kapitalisasi. jsfiddle.net/Xotic750/pSQ7d
Xotic750

1
Jika Anda benar-benar ingin menjadi bertele-tele, Anda dapat membuat regex lebih permisif: rgb.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i)Namun, regex yang diberikan dirancang untuk mengatasi format yang diberikan oleh browser saat menggunakan jQuery, dan ini tidak memiliki konsistensi white-space atau captilisation yang berbeda. kamu berbicara tentang. Anda juga bisa menggunakan regex yang sama dan hanya menghapus semua spasi putih dan mengubahnya menjadi huruf kecil sebelum cocok dengan rgb. PS Contoh biola Anda: 'rgb (10, 128,)' Saya pikir itu tidak masuk akal untuk diuji
binderbound

dan bagi saya kembalinya warna latar jquery css datang dalam format dengan rgba, jadi ini tidak berfungsi.
Miguel

159

Berikut adalah solusi bersih yang saya tulis berdasarkan saran @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]);
}

Beberapa browser sudah mengembalikan warna sebagai heksadesimal (pada Internet Explorer 8 dan di bawah). Jika Anda perlu menangani kasus-kasus itu, cukup tambahkan kondisi di dalam fungsi, seperti yang disarankan @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]);
}

Jika Anda menggunakan jQuery dan menginginkan pendekatan yang lebih lengkap, Anda dapat menggunakan CSS Hooks yang tersedia sejak jQuery 1.4.3, seperti yang saya tunjukkan ketika menjawab pertanyaan ini: Dapatkah saya memaksa jQuery.css ("backgroundColor") kembali dalam format heksadesimal?


2
Saya menyarankan kepada semua orang: lihat respons saya di sini untuk melihat versi yang ditingkatkan menggunakan jQuery CSS Hooks .
Erick Petrucelli

1
@ Higigo, maaf tapi kamu salah. IE8 sudah kembali warna sebagai heksadesimal ketika mendapatkan gaya saat ini, cara ini: document.getElementById("your_id").currentStyle["backgroundColor"]. Fungsi rgb2hex()tidak diperlukan. Berikut plugin jQuery menggunakan CSS Hooks yang saya sarankan di atas, yang sudah melakukan semua validasi untuk memulihkan warna di browser yang berbeda: stackoverflow.com/questions/6177454/…
Erick Petrucelli

2
@ Ghigo, saya pikir Anda salah paham: Anda TIDAK HARUS menggunakan fungsi ini jika Anda berada di browser yang kembali dalam HEX. Fungsi ini mengubah RGB ke HEX dan hanya itu. Jangan menggunakannya saat tidak dalam RGB. Fakta bahwa Anda memerlukan solusi yang lebih lengkap (yang mendeteksi jika nilainya sudah RGB, seperti yang dibuat oleh @ Jim-F) tidak mengubah fakta bahwa solusi ini menawarkan persis apa yang diminta oleh OP. Downvote Anda tidak masuk akal, maaf.
Erick Petrucelli

4
Saya minta maaf tapi saya tidak setuju. Fungsi lintas browser selalu lebih baik daripada yang membutuhkan eksekusi berdasarkan deteksi browser. Op diminta untuk mengkonversi $('#selector').css('backgroundColor')ke hex, bukan nilai rgb ke hex. Dan pada IE8, $('#selector').css('backgroundColor')sudah hex sehingga harus ditangani. Itu dia. Jangan marah padaku :)
Ghigo

1
Lakukan ini teman-teman, satu liner sederhana yang saya tambahkan ke rgb2hex()fungsi, terima kasih @ErickPetru! Saya harus kode kembali ke IE7 percaya atau tidak. Dengan .css('backgroundColor')dan asli obj.style.backgroundColorIE7 & 8 akan mengembalikan hex, bukan RGB, jadi saya menambahkan ini sebagai baris pertama dalam rgb2hex()fungsi dalam jawaban yang disediakan sehingga bekerja sepanjang jalan kembali ke 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 # symbolHarapan yang membantu.
gfrobenius

61

Sebagian besar browser tampaknya mengembalikan nilai RGB saat menggunakan:

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

Hanya IE (hanya 6 yang diuji sejauh ini) yang mengembalikan nilai Hex.

Untuk menghindari pesan kesalahan di IE, Anda bisa membungkus fungsi dalam pernyataan 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
Yang ini bekerja lebih baik daripada kebanyakan orang lain, karena Jim memperhitungkan rgba, yang digunakan Safari (setidaknya pada Mac OS X). Terima kasih, Jim!
Pascal Lindelauf

1
Solusi bagus Perhatikan bahwa fungsi mengembalikan huruf kecil yaitu # ff5544 bukan # FF5544.
Peter

Regex ini akan mendukung saluran aplha juga dalam solusi di atas rgb = rgb.match (/ ^ rgba? ((\ D +), \ s * (\ d +), \ s * (\ d +) (?:, \ S * (0 \. \ D +))?) $ /);
Musim Dingin Henning

bekerja seperti pesona
ucMedia

22

Pembaruan @ErickPetru untuk kompatibilitas 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]);
}

Saya memperbarui regex agar sesuai dengan nilai alpha jika didefinisikan, tetapi tidak menggunakannya.


Hanya untuk kelengkapan: Saya sedang mengerjakan sesuatu yang akan diekspor ke PowerPoint (jangan tanya ...), dan ia menerima byte keempat pada string hex untuk saluran alpha, sehingga orang dapat menggunakannya seperti ini: 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)) : ''); Juga saya menghapus #simbol untuk membuatnya agnostik dari penggunaan akhir (orang bisa mendapatkan output dan menambahkannya dengan 0xmisalnya, atau membiarkannya tanpa awalan). Semoga ini bisa membantu seseorang!
Óscar Gómez Alcañiz

10

Berikut ini ES6 one liner yang tidak menggunakan 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
Terima kasih, itu membantu saya memasukkannya ke halaman Wordpress yang menghapus garis miring terbalik pada jawaban sebelumnya.
Jason

5

Berikut adalah versi yang juga memeriksa transparan, saya memerlukan ini karena objek saya adalah untuk memasukkan hasilnya ke atribut style, di mana versi transparan warna hex sebenarnya adalah kata "transparan".

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

Fungsi yang mengembalikan warna latar belakang elemen dalam 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;
}

contoh penggunaan:

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

jsfiddle


4

Jawaban yang sama seperti @Jim F jawab tetapi sintaks ES6 , jadi, kurang instruksi:

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

kelas warna yang diambil dari pemilih warna 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
        };
    }
};

Cara Penggunaan

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

3

Dapat dibaca && Reg-exp gratis (tidak ada Reg-exp)

Saya telah membuat fungsi yang menggunakan fungsi dasar yang dapat dibaca dan tanpa reg-exps.
Fungsi menerima warna dalam format CSS hex, rgb atau rgba dan mengembalikan representasi hex.
EDIT: ada bug dengan parsing out format rgba (), diperbaiki ...

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
Tidak bekerja di rgba (0,0,0,0). Pertama: pesanan harus diubah. .replace("rgba", "") .replace("rgb", "") .replace("(", "") .replace(")", "");Jika tidak, Anda mendapatkan a0,0,0,0. Dan, ia mengembalikan # 000000, yang Hitam, bukan transparan.
Twelve24

Jika nilai ke-4 dalam rgba adalah 0 (nol), maka untuk css untuk 'elemen' itu adalah: elemen {color: # 000000, opacity: 0,0;} yang transparan atau hanya mengembalikan kondisional 'rgba (0,0 , 0,0) kembali ke penelepon.
Twelve24

@ Twelve24 Parsing diperbaiki - Saya benar-benar memperhatikan bahwa sebelum membaca komentar Anda, tapi jelas terima kasih untuk itu :), Adapun transparansi - fungsi seharusnya mengembalikan warna HEXA, atau "warna dasar" - sehingga orang sengaja :)
jave.web

3

Mencoba

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

Yang ini terlihat sedikit lebih bagus:

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

one-liner yang lebih ringkas:

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

memaksa jQuery untuk selalu mengembalikan 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

Hanya dengan menambahkan jawaban @ Justin di atas ..

harus

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

Karena fungsi int parse di atas memotong nol terkemuka, maka menghasilkan kode warna yang salah dari 5 atau 4 huruf mungkin ... yaitu untuk rgb (216, 160, 10) ia menghasilkan # d8a0a sedangkan seharusnya # d8a00a.

Terima kasih


1

Inilah solusi yang saya temukan yang tidak melempar kesalahan penulisan skrip di IE: http://haacked.com/archive/2009/12/29/convert-rgb-to-hex.aspx


Dalam versi IE yang lebih lama, mengambil nilai warna suatu objek menggunakan jquery kadang-kadang dapat mengembalikan hex bukan rgb, sementara sebagian besar browser modern mengembalikan RGB. Yang ditautkan ke fungsi menangani kedua kasus penggunaan
Paul T

1

Jawaban Steven Pribilinskiy menurunkan angka nol di depan, misalnya # ff0000 menjadi # ff00.

Solusinya adalah dengan menambahkan 0 terkemuka dan substring dari 2 digit terakhir.

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

Karena pertanyaannya menggunakan JQuery, inilah plugin JQuery berdasarkan kode 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));
};

Gunakan seperti:

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

0

Berikut ini adalah solusi saya, juga mengatasi dengan menggunakan argumen dan memeriksa ruang putih lain dan kapitalisasi pada string yang disediakan.

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

Di jsfiddle

Perbandingan kecepatan di jsperf

Sebuah perbaikan lebih lanjut bisa untuk trim()yang rgbstring yang

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

0

Solusi non-standar cantik saya

HTML

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

jQuery

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

Hasil

#f5b405

1
Ia mengembalikan segala sesuatu dengan gaya. : c
Eddie
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.