将十六进制转换为 RGBA

Posted

技术标签:

【中文标题】将十六进制转换为 RGBA【英文标题】:Convert Hex to RGBA 【发布时间】:2014-03-05 23:39:32 【问题描述】:

我的小提琴 - http://jsbin.com/pitu/1/edit

我想尝试一个简单的 hex 到 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

【问题讨论】:

TinyColor 是一个很棒的颜色处理 js 库,可以在这里完成我想要的一切以及更多。我想你们可能想试一试! 【参考方案1】:

经过这么多年,仅作记录,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);

【讨论】:

【参考方案2】:
//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)
*/

【讨论】:

谢谢你..奇迹般地工作..:) 很容易理解的解决方案,但它不支持像#ff0000aa这样的8位十六进制? 如果输入不完全是 3 或 6 个字符,这将不起作用。 @KehlanKrumme 你的例子是什么?【参考方案3】:

试试

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 ? @AlexanderCherednichenko 你是对的 - 谢谢 - 已修复【参考方案4】:

干净的 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 的回答。

【讨论】:

这在某些情况下并非每次都有效,它为 r、g 或/和 b 返回 NaN。 为我解决了!谢谢 else 不应该返回rgb($r, $g, $b),因为它没有 alpha 版本吗? @AmanshuKataria 是的,应该。好地方。 不需要else ,因为您返回if。也可以考虑单行:return alpha ? `rgba($r, $g, $b, $alpha)` : `rgb($r, $g, $b)`【参考方案5】:

其实,我喜欢使用 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)`;
;

【讨论】:

【参考方案6】:

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

【讨论】:

简单而简短,谢谢!对于 1-liner 并将结果作为数组返回(假设不需要 alpha,就像我的情况一样),可以使用:return [parseInt(hex.slice(1, 3), 16), parseInt(hex.slice(3, 5), 16), parseInt(hex.slice(5, 7), 16)];【参考方案7】:

我只是把它放在这里:

(str, alpha) => 


    if(!/^#([A-Fa-f0-9]3)1,2$/.test(str))
      throw new Error('Bad hex')


    let c = str.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, $alpha)`;

;

【讨论】:

【参考方案8】:

这是一个支持 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 字符串并返回。

【讨论】:

【参考方案9】:

无需重新实现***:

RGB 转十六进制:https://github.com/sindresorhus/rgb-hex 十六进制转 RGB:https://github.com/sindresorhus/hex-rgb

【讨论】:

有时重新设计车轮会让您的骑行更顺畅... 车轮设计师会这么说.. :D【参考方案10】:

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

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

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 可以通过以下方式提供给函数:

    作为 4 或 8 形式 HEX 的一部分。 作为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。 @George,谢谢!在创建这个之后,我问自己是否真的需要这样一个全面的方法。您的反馈很有价值。 我认为 alpha calc 中可能存在 1 个小错误。我认为它应该是:return a / 255 否则 FF 不会返回 1 @DustinKerstein 不错!可能不会造成伤害,但仍应修复。 这是最好的答案,它适用于所有单元测试。【参考方案11】:

添加到@ElDoRado1239

对于那些想要传递 alpha 值的人(打字稿 sn-p):

static hexToRGB(hex: string, alpha: number): string 
    var h = "0123456789ABCDEF";
    var r = h.indexOf(hex[1]) * 16 + h.indexOf(hex[2]);
    var g = h.indexOf(hex[3]) * 16 + h.indexOf(hex[4]);
    var b = h.indexOf(hex[5]) * 16 + h.indexOf(hex[6]);
    if (alpha) 
      return `rgba($r, $g, $b, $alpha)`
    

    return `rgba($r, $g, $b)`;
  

【讨论】:

【参考方案12】:

将带有 alpha (ahex) 的 HEX 转换为 rgba。

function ahex_to_rba(ahex) 
    //clean #
    ahex = ahex.substring(1, ahex.length);
    ahex = ahex.split('');

    var r = ahex[0] + ahex[0],
        g = ahex[1] + ahex[1],
        b = ahex[2] + ahex[2],
        a = ahex[3] + ahex[3];

    if (ahex.length >= 6) 
        r = ahex[0] + ahex[1];
        g = ahex[2] + ahex[3];
        b = ahex[4] + ahex[5];
        a = ahex[6] + (ahex[7] ? ahex[7] : ahex[6]);
    

    var int_r = parseInt(r, 16),
        int_g = parseInt(g, 16),
        int_b = parseInt(b, 16),
        int_a = parseInt(a, 16);


    int_a = int_a / 255;

    if (int_a < 1 && int_a > 0) int_a = int_a.toFixed(2);

    if (int_a || int_a === 0)
        return 'rgba('+int_r+', '+int_g+', '+int_b+', '+int_a+')';
    return 'rgb('+int_r+', '+int_g+', '+int_b+')';

用 sn-p 自己试试吧:

function ahex_to_rba(ahex) 
    //clean #
    ahex = ahex.substring(1, ahex.length);
    ahex = ahex.split('');

    var r = ahex[0] + ahex[0],
        g = ahex[1] + ahex[1],
        b = ahex[2] + ahex[2],
        a = ahex[3] + ahex[3];

    if (ahex.length >= 6) 
        r = ahex[0] + ahex[1];
        g = ahex[2] + ahex[3];
        b = ahex[4] + ahex[5];
        a = ahex[6] + (ahex[7] ? ahex[7] : ahex[6]);
    

    var int_r = parseInt(r, 16),
        int_g = parseInt(g, 16),
        int_b = parseInt(b, 16),
        int_a = parseInt(a, 16);


    int_a = int_a / 255;

    if (int_a < 1 && int_a > 0) int_a = int_a.toFixed(2);

    if (int_a || int_a === 0)
        return 'rgba('+int_r+', '+int_g+', '+int_b+', '+int_a+')';
    return 'rgb('+int_r+', '+int_g+', '+int_b+')';



$(function() 
  $('#go').click(function() 
    $('p b').text(ahex_to_rba($('#hex').val()));
  )
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="hex" type="text" value="#ffaaffaa">
<input id="go" type="button" value="Go">

<p>Result: <b></b></p>

Original Author

【讨论】:

【参考方案13】:

还有一个基于位移的。

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

【讨论】:

【参考方案14】:

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)

【讨论】:

由于toString on Array, 连接,并且事实输入可以是rrggbbaa hex,您可以将其更改为 const rgb = hex.match(...).slice(0 ,3).map(...) returnn`$rgb,$alpha`; 下面的代码也会转换 hex2rgba('#369', 0.5); var hex2rgba = (hex, alpha = 1) => const [r, g, b] = hex.match(hex.length parseInt(x.length$x$x: x, 16));返回rgba($r,$g,$b,$alpha); ;【参考方案15】:

ES6 现代、无RegEx、具有错误检查和常量箭头功能的解决方案,错误返回null。如果没有给出 alpha,则使用默认值 1:

const hexToRGB = (hex, alpha = 1) => 
    let parseString = hex;
    if (hex.startsWith('#')) parseString = hex.slice(1, 7);
    if (parseString.length !== 6) return null;
    const r = parseInt(parseString.slice(0, 2), 16);
    const g = parseInt(parseString.slice(2, 4), 16);
    const b = parseInt(parseString.slice(4, 6), 16);
    if (isNaN(r) || isNaN(g) || isNaN(b)) return null;
    return `rgba($r, $g, $b, $alpha)`;
;

注意:它返回 null 以表示错误。您可以用 throw 语句替换 return null;throw "Not a valid hex color!";,但是您应该从内部调用它 try-catch:

hexToRGB("#3454r5") => null
hexToRGB("#345465") => rgba(52, 84, 101, 1)
hexToRGB("#345465", 0.5) => rgba(52, 84, 101, 0.5)

【讨论】:

【参考方案16】:

这是一个 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(', '))`;

【讨论】:

【参考方案17】:

我喜欢@AJFarkas 的答案,并在其中添加了对快捷方式十六进制 (#fff) 的支持

function hexToRGB(hex, alpha) 
    if (!hex || [4, 7].indexOf(hex.length) === -1) 
        return; // throw new Error('Bad Hex');
    

    hex = hex.substr(1);
    // if shortcuts (#F00) -> set to normal (#FF0000)
    if (hex.length === 3)  
        hex = hex.split('').map(function(el) 
              return el + el + '';
            ).join('');
    

    var r = parseInt(hex.slice(0, 2), 16),
        g = parseInt(hex.slice(2, 4), 16),
        b = parseInt(hex.slice(4, 6), 16);

    if (alpha !== undefined) 
        return "rgba(" + r + ", " + g + ", " + b + ", " + alpha + ")";
     else 
        return "rgb(" + r + ", " + g + ", " + b + ")";
    


document.write(hexToRGB('#FF0000', 0.5));
document.write('<br>');
document.write(hexToRGB('#F00', 0.4));

【讨论】:

【参考方案18】:

如果您提供 alpha,这里有一个返回 rgb 或 rgba 的函数。该函数还可以转换短的十六进制颜色代码。

功能:

function hexToRgb(hex, alpha) 
   hex   = hex.replace('#', '');
   var r = parseInt(hex.length == 3 ? hex.slice(0, 1).repeat(2) : hex.slice(0, 2), 16);
   var g = parseInt(hex.length == 3 ? hex.slice(1, 2).repeat(2) : hex.slice(2, 4), 16);
   var b = parseInt(hex.length == 3 ? hex.slice(2, 3).repeat(2) : hex.slice(4, 6), 16);
   if ( alpha ) 
      return 'rgba(' + r + ', ' + g + ', ' + b + ', ' + alpha + ')';
   
   else 
      return 'rgb(' + r + ', ' + g + ', ' + b + ')';
   

示例:

hexToRgb('FF0000');// rgb(255, 0, 0)
hexToRgb('#FF0000');// rgb(255, 0, 0)
hexToRgb('#FF0000', 1);// rgba(255, 0, 0, 1)
hexToRgb('F00');// rgb(255, 0, 0)
hexToRgb('#F00');// rgb(255, 0, 0)
hexToRgb('#F00', 1);// rgba(255, 0, 0, 1)

【讨论】:

【参考方案19】:

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

【讨论】:

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

如果有帮助,纯 JS 解决方案:

function hexToRGB(hex,alphaYes)
 var h = "0123456789ABCDEF";
 var r = h.indexOf(hex[1])*16+h.indexOf(hex[2]);
 var g = h.indexOf(hex[3])*16+h.indexOf(hex[4]);
 var b = h.indexOf(hex[5])*16+h.indexOf(hex[6]);
 if(alphaYes) return "rgba("+r+", "+g+", "+b+", 1)";
 else return "rgb("+r+", "+g+", "+b+")";

"alphaYes" 是 "true" 或 "false" 取决于您是否需要 alpha。

【讨论】:

在这种情况下,else 关键字是不必要的。无论如何,它都会返回非 alpha。 哦,是的,但这对我来说似乎更“整洁”。我猜只是个人喜好问题。 此代码不适用于小写十六进制(例如#f0a16e)。我建议先将hex 转换为toUpperCase【参考方案21】:

试试这个

<div class="torgb" onclick="rgba();" style="background-color:#000; width:20px; height:20px;"></div>
<script>
function rgba()
$('.torgb').attr('background-color','rgba(0,0,0,1)');
$('.torgb').attr('onclick','hex();');

function hex()
$('.torgb').attr('background-color','#000');
$('.torgb').attr('onclick','rgba();');

</script>

【讨论】:

hexrgba 函数从何而来?

以上是关于将十六进制转换为 RGBA的主要内容,如果未能解决你的问题,请参考以下文章

ruby 将十六进制颜色转换为RGBA

将 8 位十六进制颜色转换为 rgba 颜色?

SASS:将 RGBa 转换回十六进制?

将 RGBA 转换为 HEX

将rgb转换为十六进制

如何将 UIColor 转换为十六进制字符串?