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?

bfavaretto
sumber
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 )

Daniel Elliott
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?

Erick Petrucelli
sumber
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]); 
     }
}
Jim F
sumber
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.

Zack Katz
sumber
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('');
Justin McCandless
sumber
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]); 
     }
}
Matt Welander
sumber
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

shaik
sumber
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]);
};
Abdennour TOUMI
sumber
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()
Fareed Alnamrouti
sumber
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);
}
jave.web
sumber
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``

Kamil Kiełczewski
sumber
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]);
        }
    }
}
Steven Pribilinskiy
sumber
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

Yogesh Kumar Gupta
sumber
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

Mike
sumber
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);
pengguna2874310
sumber
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');
Tom Söderlund
sumber
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),
Xotic750
sumber
0

Solusi non-standar cantik saya

HTML

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

jQuery

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

Hasil

#f5b405
Baru dikenali
sumber
1
Ia mengembalikan segala sesuatu dengan gaya. : c
Eddie