记一次HEX和RGB互换算法的思考及应用

徐小夕
• 阅读 1486

由于笔者最近在开发可视化平台,所以对动态编辑器这块做了一段时间的研究, 发现其中有个小模块的知识点比较有意思,所以在这里分享一下.

作为前端工程师, 我们平时在对接设计稿的时候, 是不是经常会涉及到颜色值的转换呢? 比如从HEX值转化到RGB值, 亦或者是从RGB值转换到HEX值, 这块在PhotoShop等设计软件中非常常见, 在做类似于画板, 设计类的IDE的时候也经常会用到它们的互相转换, 还有一种场景是,为了满足老板对高大上特效的要求, 我们要让动画在不同的时间显示不同的颜色,而且有过渡效果(过渡效果虽然可以通过transiton来实现),如下:

记一次HEX和RGB互换算法的思考及应用

记一次HEX和RGB互换算法的思考及应用

记一次HEX和RGB互换算法的思考及应用

所以笔者在这里就分享一下HEXRGB之间相互转换的原理和算法, 并且实现随机生成HEX值随机生成RGB值的函数,最后带着大家深度理解和掌握颜色领域的应用.

1 文章摘要

  • HEX与16进制
  • HEX转RGB算法
  • RGB转HEX算法
  • 应用场景

2 HEX(16进制)

十六进制(英文名称:Hexadecimal),是计算机中数据的一种表示方法。和我们平常的表示法不一样。它由0-9,A-F组成,字母不区分大小写。与10进制的对应关系是:0-9对应0-9;A-F对应10-15;N进制的数可以用0~(N-1)的数表示,超过9的用字母A-F。

以上概念非常重要, 这也是我们转换RGB的关键. 还有一个知识点需要我们掌握的就是进制转换. 在计算机基础中我们都知道如何将二进制转化为十进制, 10进制数转换成16进制的方法,和转换为2进制的方法类似,唯一的变化:除数由2变成16. 举个例子, 我们拿140来举例:

被除数 计算过程 余数
140 140/16 8 12
8 8/16 0 8

所以140转换为16进制,结果为:8C (由十六进制的定义我们知道14对应的字母为E)

以上就是掌握HEX和RGB互相转换的核心知识点, 接下来我们来看看互相转换的算法实现.

3 HEX转RGB算法

HEX 颜色值转换成 RGB 颜色值,本质上是HEX的第一位数乘以16加上第二位数. 举个例子: 转换颜色为 #1821DD的 HEX 值到 RGB 值.

#1821DD ----------> rgb:

18 ----> r: r的值就是: 1 * 16 + 8 = 24

21 ----> g: g的值就是: 2 * 16 + 1 = 33

DD ----> b: b的值就是: 13 * 16 + 13 = 221

以上转换的结果为rgb: (24, 33, 221), 怎么样, 是不是很简单? 接下来我们来看看具体的算法实现:

const hex2rgb = (hex: string = ''):string => {
  //  针对于传入错误的hex,即长度不等于7或者不等于4的
  if(![4,7].includes(hex.length)) {
    throw new Error('格式错误') 
  }

  let result = hex.slice(1)

  // 如果是颜色叠值, 统一转换成6位颜色值
  if(result.length === 3) {
    result = result.split('').map(a => `${a}${a}`).join('')
  }

  const rgb:number[] = []

  // 计算hex值
  for(let i=0, len = result.length; i< len; i+=2) {
    rgb[i / 2] = getHexVal(result[i]) * 16 + getHexVal(result[i+1])
  }

  function getHexVal(letter:string):number {
    let num:number = -1;
    switch(letter.toUpperCase()) {
      case "A":
        num = 10
        break;
      case "B":
        num = 11
        break;
      case "C":
        num = 12
        break;
      case "D":
        num = 13
        break;
      case "E":
        num = 14
        break;
      case "F":
        num = 15
        break;
    }

    if(num < 0) {
      num = Number(letter)
    }

    return num
  }

  return `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`
}

当然还有更其他方法可以实现REXRGB, 大家可以自行探索.

4 RGB转HEX算法

对于RGB转HEX, 方法类似, 只不过相当于上述方法的逆运算, 笔者实现一种思路, 大家可以参考学习:

const rgb2hex = (rgb: string):string => {
  let str = rgb.replace(/rgb\((.*)\)/g, '$1')
  let strArr = str.split(',').map(t => t.trim())

  let result:string[] = []

  for(let i:number = 0, len:number = strArr.length; i < len; i++) {
    let curVal = Number(strArr[i])
    let left = getHexStr(String(Math.floor(curVal / 16)))
    let right = getHexStr(String(Math.floor(curVal % 16)))
    result[i] = left  + right
  }

  function getHexStr(v:string):string {
    let str:string = '';
    switch(v) {
      case '10':
        str = "A"
        break;
      case '11':
        str = "B"
        break;
      case '12':
        str = "C"
        break;
      case '13':
        str = "D"
        break;
      case '14':
        str = "E"
        break;
      case '15':
        str = "F"
        break;
    }

    if(!str) {
      str = v
    }

    return str
  }

  return `#${result.join('')}`
}

以上就是反转的算法, 大家掌握了吗?接下来我们来聊聊它的应用场景.

5 应用场景

其实颜色单位互换应用在很多领域, 笔者先罗列几个实际场景:

  • 单位换算工具

记一次HEX和RGB互换算法的思考及应用

  • WEB IDE调色板

记一次HEX和RGB互换算法的思考及应用

  • 动态背景

记一次HEX和RGB互换算法的思考及应用

记一次HEX和RGB互换算法的思考及应用

其实还有很多应用, 大家可以自行发挥哈, 今天的学习就到这了, 请问今天你又博学了吗?

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
3年前
HIVE 时间操作函数
日期函数UNIX时间戳转日期函数: from\_unixtime语法:   from\_unixtime(bigint unixtime\, string format\)返回值: string说明: 转化UNIX时间戳(从19700101 00:00:00 UTC到指定时间的秒数)到当前时区的时间格式举例:hive   selec
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这