将十六进制转换为 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>
【讨论】:
hex
和 rgba
函数从何而来?以上是关于将十六进制转换为 RGBA的主要内容,如果未能解决你的问题,请参考以下文章