1

Currently I am heaving problems using this really simple bit of code: field.style.backgroundColor="#ffffff"; Till now it has worked fine for me, but just recently I noticed that in webkit the hex values is always converted to rgb values like rgb(255, 255, 255). Usually that wouldn't be a problem, but I need the hex values later on in a php script creating an image. And converting them back just slows down the whole process. So my really basic question is how can I avoid getting those annoying rgb values.

Philipp Braun
  • 1,583
  • 2
  • 25
  • 41
  • 1
    See http://stackoverflow.com/questions/6177454/can-i-force-jquery-cssbackgroundcolor-returns-on-hexadecimal-format and http://stackoverflow.com/questions/1740700/get-hex-value-rather-than-rgb-value-using-jquery. Apparently, all browsers but IE6 do that. – bfavaretto Apr 26 '13 at 22:11

3 Answers3

2

It is actually fairly trivial to write your own converters, and it is a really fast calculation, by why reinvent the wheel when there is one with a pneumatic tyre already fitted? :) Have a look at colours javascript library.

Ok, so the library wasn't your thing, here is a function to do it for you.

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 jsfiddle

And here are the jsperfs

Xotic750
  • 22,914
  • 8
  • 57
  • 79
2

You can split the value into it's parts, convert each number to hexidecimal, then return a formatted string, e.g.:

// convert rgb colour values to hex, e.g. rgb(255, 255, 255) to #ffffff;
function rgbToHex(rgb) {
  var re = /^rgb\(.*\)$/;
  var bits;
  function z(n){return (n<10?'0':'') + n;}

  if (re.test(rgb)) {
    bits = rgb.match(/\d+/g);
    return '#' + z((+bits[0]).toString(16)) + 
                 z((+bits[1]).toString(16)) +
                 z((+bits[2]).toString(16));
  }
  return rgb;
}

alert(rgbToHex('rgb(255, 255, 255)')); // #ffffff   
alert(rgbToHex('rgb(0, 0, 0)')); // #000000
alert(rgbToHex('rgb(100, 230, 90)')); // #64e65a

You might need an i flag on the test regular expression in case some browsers return "RGB(…)".

Edit

Based on Xotic750's post, the z function should be:

function z(n){return (n.length == 1?'0':'') + n;}

A less strict regular expression may suit too:

  var re = /^rgb/i;

The other fails are a case of garbage in, garbage out. The regular expression can be modified to allow a space in "rgb (" if required. An updated version is:

function rgbToHex(rgb) {
    var re = /^rgb/i;
    var bits = rgb.match(/\d+/g);;

    function z(n) {
        return (n.length == 1? '0' : '') + n;
    }

    if (re.test(rgb) && bits.length == 3) {
        return '#' + z((+bits[0]).toString(16))
                   + z((+bits[1]).toString(16))
                   + z((+bits[2]).toString(16));
    }
    return rgb;
}

The only choice left is if the test fails, should it return the original string or undefined?

RobG
  • 142,382
  • 31
  • 172
  • 209
  • Oh dear what happens in this testing? All seems a bit broken. http://jsfiddle.net/Xotic750/QYqCy/ – Xotic750 Apr 27 '13 at 13:39
  • @Xotic750—thanks for the test cases, small change to the regular expression test and the *z* function fixes all but the last case, which is a case of gi/go. What value should be substituted for the missing hex value? Or if only two terms are found, should it return *undefined* or the original string? – RobG Apr 27 '13 at 14:35
  • I return undefined as the input is not the correct format. But that was just my decision. Here are the test cases with you latest code: http://jsfiddle.net/Xotic750/zGhAj/ – Xotic750 Apr 27 '13 at 14:37
0

Can't you just interpret the value as a hex value in php without even the need of converting it? Actually i don't know what JavaScript hands you there exactly but if it is just single value interpret them in hex and cocatenate them.

There shouldn't be a loss of performance.

Greetings

s_qw23
  • 354
  • 2
  • 11
  • I have to convert about one hundred color values from rgb to hex. And how am I supposed to interpret the value rgb(255,255,255) as #ffffff without using any code?? Doesn't really make sense to me ... – Philipp Braun Apr 26 '13 at 21:53