将十六进制转换为RGBA

134

我的小测试 - http://jsbin.com/pitu/1/edit

我想尝试一下简单的十六进制转换为RGBA。我使用的每个浏览器都默认使用RGB来渲染颜色,因此当使用farbtastic颜色选择器时,我通过获取背景色来生成十六进制值所产生的rgb值(默认=简单转换)来将十六进制值转换为RGB。

我曾试图将)符号替换为, 1),但没有成功,所以我想看看将RGB转换为RGBA会如何工作,但我仍然遇到了困难。

JQuery

$('.torgb').val($('#color').css('background-color'));
$('.torgba').val().replace(/rgb/g,"rgba");
目标是: enter image description here 编辑: TinyColor 是一个很棒的颜色操作 JS 库,它可以满足我所有需求并且更多。我想你们也许想试试!- https://github.com/bgrins/TinyColor

2
TinyColor 是一个非常棒的颜色操作 JS 库,它可以满足我在这里所需的一切以及更多。我想你们可能想要尝试一下! - Michael Schwartz
28个回答

4

这是一个支持3、4、6和8个字符颜色代码的快速函数:

function hexToRGBA(hex) {
    // remove invalid characters
    hex = hex.replace(/[^0-9a-fA-F]/g, '');

    if (hex.length < 5) { 
        // 3, 4 characters double-up
        hex = hex.split('').map(s => s + s).join('');
    }

    // parse pairs of two
    let rgba = hex.match(/.{1,2}/g).map(s => parseInt(s, 16));

    // alpha code between 0 & 1 / default 1
    rgba[3] = rgba.length > 3 ? parseFloat(rgba[3] / 255).toFixed(2): 1;

    return 'rgba(' + rgba.join(', ') + ')';
}

这是它的功能。它会删除任何非十六进制字符。如果HEX长度小于5(3或4)个字符,它会将每个字符都加倍。然后将HEX拆分成两个字符一组,并将每个组解析为整数。如果有alpha HEX,则从0到1解析为浮点数,否则默认为1。然后连接数组形成RGBA字符串并返回。

3

这里有一个ES2015+版本,更加严谨,并处理了简写的3位数语法。

/*
 * Takes a 3 or 6-digit hex color code, and an optional 0-255 numeric alpha value
 */
function hexToRGB(hex, alpha) {
  if (typeof hex !== 'string' || hex[0] !== '#') return null; // or return 'transparent'

  const stringValues = (hex.length === 4)
        ? [hex.slice(1, 2), hex.slice(2, 3), hex.slice(3, 4)].map(n => `${n}${n}`)
        : [hex.slice(1, 3), hex.slice(3, 5), hex.slice(5, 7)];
  const intValues = stringValues.map(n => parseInt(n, 16));

  return (typeof alpha === 'number')
    ? `rgba(${intValues.join(', ')}, ${alpha})`
    : `rgb(${intValues.join(', ')})`;
}

3

function hexToRGB(hex, alpha) {
    var r = parseInt(hex.slice(1, 3), 16),
        g = parseInt(hex.slice(3, 5), 16),
        b = parseInt(hex.slice(5, 7), 16);

    if (alpha) {
        return "rgba(" + r + ", " + g + ", " + b + ", " + alpha + ")";
    } else {
        return "rgb(" + r + ", " + g + ", " + b + ")";
    }
}

hexToRGB('#FF0000', 0.5);


对于一个一行代码并将结果作为数组返回的情况(假设不需要使用字母,就像我的情况一样),可以使用以下代码:return [parseInt(hex.slice(1, 3), 16), parseInt(hex.slice(3, 5), 16), parseInt(hex.slice(5, 7), 16)]; - yenren

3

实际上,我喜欢使用ES6方法来避免使用RegExp,RegExp不安全,我不信任它。下面的答案是TypeScript,如果只需要JavaScript,请删除类型:

// TypeScript

const hex2rgba = (hex: string, alpha = 1): string => {
  if (alpha > 1 || alpha < 0) {
    throw new Error('alpha is not correct!');
  }

  const red = parseInt(hex.slice(1, 3), 16);
  const green = parseInt(hex.slice(3, 5), 16);
  const blue = parseInt(hex.slice(5, 7), 16);

  return `rgba(${red}, ${green}, ${blue}, ${alpha})`;
};

2

多年来,DOM API默认包括alpha通道在内进行转换。我是说,如果您像这样做:

tempElement.style.cssText = "color: #de1e7eaa";
console.log(tempElement.style.color) // <- rgb(222, 30, 126, 0.667)

您会得到一个RGB值的字符串。然后根据您的需求进行处理或不进行处理。如果我们足够懒惰,我们可以利用这个机会。

var color = "#de1e7eaa",                 // hex color code in string including alpha
    temp  = document.createElement("i"), // just a temporary element
    rgbStr,
    rgbInt;
temp.style.cssText = `color: ${color}`;  // assign it to the style of the <i> element
rgbStr = temp.style.color;
rgbInt = Array.from(rgbStr.matchAll(/\d+\.?\d*/g), c=> +c[0]) // temp.style.color gives RGB string
                                                              // then we convert it to Number if need be
console.log(rgbStr);
console.log(rgbInt);


1
另一个基于位移的例子。
// hex can be a string in the format of "fc9a04", "0xfc9a04" or "#fc90a4" (uppercase digits are allowed) or the equivalent number
// alpha should be 0-1
const hex2rgb = (hex, alpha) => {
  const c = typeof(hex) === 'string' ? parseInt(hex.replace('#', ''), 16)  : hex;
  return `rgb(${c >> 16}, ${(c & 0xff00) >> 8}, ${c & 0xff}, ${alpha})`;
};

1

尝试

let hex2rgba= (hex,a)=> `rgba(${hex.substr(1).match(/../g).map(x=>+`0x${x}`)},${a})`

/// hex - str e.g. "#abcdef"; a - alpha range 0-1; result e.g. "rgba(1,1,1,0)"
let hex2rgba= (hex,a)=> `rgba(${hex.substr(1).match(/../g).map(x=>+`0x${x}`)},${a})`;

function convert() {
  console.log(hex2rgba(inp.value,1));
}
<input id="inp" value="#abcdef" >
<button onclick="convert()">convert</button>


你需要在返回值中将 RGB 更新为 RGBA。 - Alexander Cherednichenko
@AlexanderCherednichenko 你是对的 - 谢谢 - 已修复 - Kamil Kiełczewski

1

适用于所有快捷键

基于@kennebec的答案,这里提供了一种解决方案,可以适用于所有十六进制颜色的快捷键(#123, #1234, #123456, #12345678)。

const hex2rgba = (hex) => {
    let c = hex.substring(1).split('');

    if (!/^#(([\dA-Fa-f]{3}){1,2}|([\dA-Fa-f]{4}){1,2})$/.test(hex)) {
        throw new Error('Your hexadecimal color is not correct.');
    }

    switch (c.length) {
        case 3:
            c = [c[0] + c[0], c[1] + c[1], c[2] + c[2], 'ff'];
            break;
        case 4:
            c = [c[0]+c[0], c[1]+c[1], c[2]+c[2], c[3]+c[3]];
            break;
        case 6:
            c = [c[0]+c[1], c[2]+c[3], c[4]+c[5], 'ff'];
            break;
        case 8:
            c = [c[0]+c[1], c[2]+c[3], c[4]+c[5], c[6]+c[7]];
            break;
    }

    c = c.map((char) => parseInt(char, 16).toString());
    c[3] = (Math.round((parseInt(c[3],10)/255)*100)/100).toString();
    return c[3] === '1'
        ? `rgb( ${c[0]}, ${c[1]}, ${c[2]})`
        : `rgba(${c[0]}, ${c[1]}, ${c[2]}, ${c[3]})`;
}

//return a rgb or rgba value according to the alpha value
console.log(hex2rgba('#af6'))
console.log(hex2rgba('#af6f'))
console.log(hex2rgba('#af64f576'))

Typescript版本

const hex2rgba = (hex: string): string => {
    let c: string[] = hex.substring(1).split('');

    if (!/^#(([\dA-Fa-f]{3}){1,2}|([\dA-Fa-f]{4}){1,2})$/.test(hex)) {
        throw new Error('Your hexadecimal color is not correct.');
    }

    switch (c.length) {
        case 3:
            c = [c[0] + c[0], c[1] + c[1], c[2] + c[2], 'ff'];
            break;
        case 4:
            c = [c[0]+c[0], c[1]+c[1], c[2]+c[2], c[3]+c[3]];
            break;
        case 6:
            c = [c[0]+c[1], c[2]+c[3], c[4]+c[5], 'ff'];
            break;
        case 8:
            c = [c[0]+c[1], c[2]+c[3], c[4]+c[5], c[6]+c[7]];
            break;
    }

    c = c.map((char) => parseInt(char, 16).toString());
    c[3] = (Math.round((parseInt(c[3],10)/255)*100)/100).toString();
    return c[3] === '1'
        ? `rgb( ${c[0]}, ${c[1]}, ${c[2]})`
        : `rgba(${c[0]}, ${c[1]}, ${c[2]}, ${c[3]})`;
}


1

对于大多数用例来说,这可能有些过度,但如果您需要一个解决方案,可以处理每个边缘情况,包括所有命名颜色,并实际将任何有效的CSS颜色字符串(而不仅仅是十六进制)转换为RGBA:

function toRGBA(cssColor) {
  let el = document.createElement("div");
  el.style.color = cssColor;
  el.style.display = "none";
  document.body.appendChild(el);
  let rgba = window.getComputedStyle(el).getPropertyValue("color");
  el.remove();
  let [r, g, b, a] = rgba.match(/[0-9.]+/g).map(n => Number(n));
  if(a === undefined) a = 1; // <-- getPropertyValue returns rgb(...) if there is no transparency, so we add alpha if missing
  return [r, g, b, a];
}

toRGBA("#34f1a8") // [52, 241, 168, 1]
toRGBA("#fe6") // [255, 238, 102, 1]
toRGBA("blue") // [0, 0, 255, 1]
toRGBA("hsl(0, 90%, 50%)") // [242, 13, 13, 1]
...

(显然,这种方法不适用于像Deno或Node.js这样的服务器端代码)

0

修改@kennebec的解决方案以具有alpha参数

function hexToRgbA(hex, alpha=1){
    if(alpha > 1) alpha = 1;
    if(alpha < 0) alpha = 0;
    var c;
    if(/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)){
        c= hex.substring(1).split('');
        if(c.length== 3){
            c= [c[0], c[0], c[1], c[1], c[2], c[2]];
        }
        c= '0x'+c.join('');
        return 'rgba('+[(c>>16)&255, (c>>8)&255, c&255].join(',')+','+alpha+')';
    }
    throw new Error('Bad Hex');
}

hexToRgbA('#fce881', 0.6);

/* returned value: (String)
rgba(252,232,129,0.6)
*/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接