将十六进制转换为 RGBA

IT技术 javascript jquery colors
2021-02-22 18:57:23

我的小提琴 - 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");

目标
在此处输入图片说明

编辑

TinyColor是一个很棒的颜色操作 js 库,它可以完成我想要的一切以及更多。我想你们可能想试一试!- https://github.com/bgrins/TinyColor

6个回答
//If you write your own code, remember hex color shortcuts (eg., #fff, #000)

function hexToRgbA(hex){
    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(',')+',1)';
    }
    throw new Error('Bad Hex');
}

hexToRgbA('#fbafff')

/*  returned value: (String)
rgba(251,175,255,1)
*/
如果输入不完全是 3 或 6 个字符,这将不起作用。
2021-05-05 18:57:23
很容易理解的解决方案,但它不支持 8 形式的十六进制,如#ff0000aa
2021-05-10 18:57:23
谢谢..像奇迹一样工作..:)
2021-05-17 18:57:23
@KehlanKrumme 你的例子是什么?
2021-05-17 18:57:23

@ElDoRado1239 有正确的想法,但还有一种更简洁的方法:

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

非常易读,我比基于 reg exp 的解决方案更喜欢它。
2021-04-22 18:57:23
eslint只是风格强制。我写的任何东西都与您的风格偏好相矛盾,这只是偶然的。事实上,例如,这不会通过我目前正在从事的项目的 linting。
2021-04-24 18:57:23
注意:这将在十六进制快捷方式上失败,例如#fff. 不过,这应该很容易修复!
2021-04-25 18:57:23
干得好!!不过有一点我不得不提。我在逗号和字符串中的 RGBA 值之间保留空格有一些不好的经验。(例如:rgba(255, 35, 234, 0.5))。特别是如果您将此值传递给另一个程序时,请注意这一点。因为有些程序不接受字符串中值之间的空格。因此,最好从最终输出中删除这些空格。
2021-04-28 18:57:23
嗯,是的,你必须给函数正确的输入......
2021-04-29 18:57:23

ES6 函数仅处理带有或不带有“#”的 6 个字符的十六进制:

const hex2rgba = (hex, alpha = 1) => {
  const [r, g, b] = hex.match(/\w\w/g).map(x => parseInt(x, 16));
  return `rgba(${r},${g},${b},${alpha})`;
};

用法:

hex2rgba('#af087b', .5)   // returns: rgba(175,8,123,0.5)
hex2rgba('af087b', .5)    // returns: rgba(175,8,123,0.5)
hex2rgba('af087b')        // returns: rgba(175,8,123,1)
下面的代码也将转换 hex2rgba('#369', 0.5); var hex2rgba = (hex, alpha = 1) => { const [r, g, b] = hex.match(hex.length<=4 ? /\w/g : /\w\w/g).map( x => parseInt(x.length<2? ${x}${x}: x, 16)); 返回rgba(${r},${g},${b},${alpha}); };
2021-04-22 18:57:23
由于toStringArray连接,和事实输入可以是rrggbbaa hex你可以将其更改为 const rgb = hex.match(...).slice(0,3).map(...) returnn`${rgb},${alpha }`;
2021-05-16 18:57:23

清洁typescript版本:

hexToRGB(hex: string, alpha: string) {

  const r = parseInt(hex.slice(1, 3), 16);
  const g = parseInt(hex.slice(3, 5), 16);
  const b = parseInt(hex.slice(5, 7), 16);

  if (alpha) {
    return `rgba(${r}, ${g}, ${b}, ${alpha})`;
  }

  return `rgb(${r}, ${g}, ${b})`;
}

基于@AJFarkas 的回答。

else {}自从你回来就不需要了if还可以考虑单线:return alpha ? `rgba(${r}, ${g}, ${b}, ${alpha})` : `rgb(${r}, ${g}, ${b})`
2021-04-21 18:57:23
在某些情况下,这并非每次都有效,它为 r、g 或/和 b 返回 NaN。
2021-04-27 18:57:23
为我工作!谢谢
2021-04-29 18:57:23
@AmanshuKataria 是的,应该。好地方。
2021-05-08 18:57:23
else 不应该返回,rgb(${r}, ${g}, ${b})因为它没有 alpha 吗?
2021-05-13 18:57:23

任何十六进制形式的module化方法

主要挑战是,截至 2018 年,有几种形式的 HEX。6 个字符的传统形式、3 个字符的缩短形式以及包括 alpha 的新的 4 和 8 个字符形式。以下函数可以处理任何十六进制形式。

const isValidHex = (hex) => /^#([A-Fa-f0-9]{3,4}){1,2}$/.test(hex)

const getChunksFromString = (st, chunkSize) => st.match(new RegExp(`.{${chunkSize}}`, "g"))

const convertHexUnitTo256 = (hexStr) => parseInt(hexStr.repeat(2 / hexStr.length), 16)

const getAlphafloat = (a, alpha) => {
    if (typeof a !== "undefined") {return a / 255}
    if ((typeof alpha != "number") || alpha <0 || alpha >1){
      return 1
    }
    return alpha
}

export const hexToRGBA = (hex, alpha) => {
    if (!isValidHex(hex)) {throw new Error("Invalid HEX")}
    const chunkSize = Math.floor((hex.length - 1) / 3)
    const hexArr = getChunksFromString(hex.slice(1), chunkSize)
    const [r, g, b, a] = hexArr.map(convertHexUnitTo256)
    return `rgba(${r}, ${g}, ${b}, ${getAlphafloat(a, alpha)})`
}

Alpha 可以通过以下方式提供给函数:

  1. 作为 4 或 8 形式的 HEX 的一部分。
  2. 作为 0-1 之间的第二个参数,

输出

    const c1 = "#f80"
    const c2 = "#f808"
    const c3 = "#0088ff"
    const c4 = "#0088ff88"
    const c5 = "#98736"

    console.log(hexToRGBA(c1))   //  rgba(255, 136, 0, 1)
    console.log(hexToRGBA(c2))   //  rgba(255, 136, 0, 0.53125)
    console.log(hexToRGBA(c3))   //  rgba(0, 136, 255, 1)
    console.log(hexToRGBA(c4))   //  rgba(0, 136, 255, 0.53125)
    console.log(hexToRGBA(c5))   //  Uncaught Error: Invalid HEX

    console.log(hexToRGBA(c1, 0.5))   //  rgba(255, 136, 0, 0.5)
    console.log(hexToRGBA(c3, 0.5))   //  rgba(0, 136, 255, 0.5)
一些浏览器支持不透明的十六进制颜色,其他不支持。这个答案对于将 8 格式的十六进制转换为 rgba 非常有用,所有浏览器都支持 rgba。
2021-04-22 18:57:23
@乔治,谢谢!在创建这个之后,我问自己是否真的有必要采用这种全面的方法。您的反馈很有value。
2021-04-27 18:57:23
这是最好的答案,它适用于所有单元测试。
2021-05-04 18:57:23
我认为 alpha calc 中可能有 1 个小错误。我认为它应该是:返回 a / 255 否则 FF 不返回 1
2021-05-08 18:57:23
@DustinKerstein 不错的收获!可能不会造成伤害,但仍然应该修复。
2021-05-11 18:57:23