如何将颜色在RGB格式转换为十六进制格式,反之亦然?

例如,将'#0080C0'转换为(0,128,192)。


当前回答

结合使用匿名函数和数组。地图为清洁工;更流线型的外观。

var write=function(str){document.body.innerHTML=JSON.stringify(str,null,' ');}; function hexToRgb(hex, asObj) { return (function(res) { return res == null ? null : (function(parts) { return !asObj ? parts : { r : parts[0], g : parts[1], b : parts[2] } }(res.slice(1,4).map(function(val) { return parseInt(val, 16); }))); }(/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex))); } function rgbToHex(r, g, b) { return (function(values) { return '#' + values.map(function(intVal) { return (function(hexVal) { return hexVal.length == 1 ? "0" + hexVal : hexVal; }(intVal.toString(16))); }).join(''); }(arguments.length === 1 ? Array.isArray(r) ? r : [r.r, r.g, r.b] : [r, g, b])) } // Prints: { r: 255, g: 127, b: 92 } write(hexToRgb(rgbToHex(hexToRgb(rgbToHex(255, 127, 92), true)), true)); body{font-family:monospace;white-space:pre}

其他回答

@ Tim,补充一下你的答案(把这个放进评论里有点尴尬)。

正如所写的,我发现rgbToHex函数返回一个包含元素的字符串,它要求r, g, b值落在0-255的范围内。

我相信这对大多数人来说是显而易见的,但我花了两个小时才弄明白,到那时,原来的方法已经膨胀到7行,直到我意识到我的问题在其他地方。因此,为了节省其他人的时间和麻烦,下面是我稍微修改过的代码,它检查了先决条件,并删除了字符串中无关的部分。

function rgbToHex(r, g, b) {
    if(r < 0 || r > 255) alert("r is out of bounds; "+r);
    if(g < 0 || g > 255) alert("g is out of bounds; "+g);
    if(b < 0 || b > 255) alert("b is out of bounds; "+b);
    return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1,7);
}

hexToRgb的另一个版本:

function hexToRgb(hex) {
    var bigint = parseInt(hex, 16);
    var r = (bigint >> 16) & 255;
    var g = (bigint >> 8) & 255;
    var b = bigint & 255;

    return r + "," + g + "," + b;
}

编辑:3/28/2017 这是另一种似乎更快的方法

function hexToRgbNew(hex) {
  var arrBuff = new ArrayBuffer(4);
  var vw = new DataView(arrBuff);
  vw.setUint32(0,parseInt(hex, 16),false);
  var arrByte = new Uint8Array(arrBuff);

  return arrByte[1] + "," + arrByte[2] + "," + arrByte[3];
}

编辑:8/11/2017 经过更多测试后,上面的新方法并没有更快:(。虽然这是一种有趣的替代方式。

(2017) SIMPLE ES6组合箭头函数

我忍不住要把这个分享给那些可能正在使用ES6编写一些现代函数/复合js的人。下面是我在一个颜色模块中使用的一些光滑的单行程序,它为数据可视化做颜色插值。

注意,这根本不处理alpha通道。

const arrayToRGBString = rgb => `rgb(${rgb.join(',')})`;
const hexToRGBArray = hex => hex.match(/[A-Za-z0-9]{2}/g).map(v => parseInt(v, 16));
const rgbArrayToHex = rgb => `#${rgb.map(v => v.toString(16).padStart(2, '0')).join('')}`;
const rgbStringToArray = rgb => rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/).splice(1, 3)
  .map(v => Number(v));
const rgbStringToHex = rgb => rgbArrayToHex(rgbStringToArray(rgb));

顺便说一句,如果你喜欢这种风格/语法,我写了一个全彩色模块(modern-color),你可以从npm中获取。我这样做,所以我可以使用道具getter转换和解析几乎任何东西(Color.parse(anything))。如果你和我一样对颜色很敏感的话,值得一看。

这个代码片段将十六进制转换为rgb, rgb转换为十六进制。

视图演示

function hexToRgb(str) { 
    if ( /^#([0-9a-f]{3}|[0-9a-f]{6})$/ig.test(str) ) { 
        var hex = str.substr(1);
        hex = hex.length == 3 ? hex.replace(/(.)/g, '$1$1') : hex;
        var rgb = parseInt(hex, 16);               
        return 'rgb(' + [(rgb >> 16) & 255, (rgb >> 8) & 255, rgb & 255].join(',') + ')';
    } 

    return false; 
}

function rgbToHex(red, green, blue) {
    var out = '#';

    for (var i = 0; i < 3; ++i) {
        var n = typeof arguments[i] == 'number' ? arguments[i] : parseInt(arguments[i]);

        if (isNaN(n) || n < 0 || n > 255) {
            return false;
        }

        out += (n < 16 ? '0' : '') + n.toString(16);
    }
    return out
}

建立了我自己的十六进制RGB转换器。我希望这能帮助到一些人。

我用react来做沙盒。

用法:

根据官方文档安装React,或者如果你全局安装了npx,运行npx create-react-app hexto -rgb

import React, { Component, Fragment } from 'react';
const styles = {
  display: 'block',
  margin: '20px auto',
  input: {
    width: 170,
  },
  button: {
    margin: '0 auto'
  }
}

//  test case 1
//    #f0f
//  test case 2
//    #ff00ff

class HexToRGBColorConverter extends Component {

  state = {
    result: false,
    color: "#ff00ff",
  }
  
  hexToRgb = color => {    
    let container = [[], [], []];
    // check for shorthand hax string
    if (color.length >= 3) {
      // remove hash from string
      // convert string to array
      color = color.substring(1).split("");
      for (let key = 0; key < color.length; key++) {        
        let value = color[key];
        container[2].push(value);
        // if the length is 3 we 
        // we need to add the value 
        // to the index we just updated
        if (color.length === 3) container[2][key] += value;
      }
      
      for (let index = 0; index < color.length; index++) {
        let isEven = index % 2 === 0;
        // If index is odd an number 
        // push the value into the first
        // index in our container
        if (isEven) container[0].push(color[index]);
        // If index is even an number 
        if (!isEven) {
          // again, push the value into the
          // first index in the container
          container[0] += color[index];
          // Push the containers first index
          // into the second index of the container
          container[1].push(container[0]);
          // Flush the first index of
          // of the container 
          // before starting a new set
          container[0] = [];
        }
      }
      // Check container length
      if (container.length === 3) {
        // Remove only one element of the array
        // Starting at the array's first index
        container.splice(0, 1);
        let values = container[color.length % 2];
        return {
          r: parseInt(values[0], 16),
          g: parseInt(values[1], 16),
          b: parseInt(values[2], 16)
        }
      }
    }
    return false;
  }  

  handleOnClick = event => {
    event.preventDefault();
    const { color } = this.state;
    const state = Object.assign({}, this.state);
    state.result = this.hexToRgb(color);
    this.setState(state);
  }

  handleOnChange = event => {
    event.preventDefault();
    const { value } = event.currentTarget;
    const pattern = /^([a-zA-Z0-9])/;
    const boundaries = [3, 6];
    if (
      pattern.test(value) &&
      boundaries.includes(value.length)
    ) {
      const state = Object.assign({}, this.state);
      state.color = `#${value}`;
      this.setState(state);
    }
  }

  render() {
    const { color, result } = this.state;
    console.log('this.state ', color, result);

    return (
      <Fragment>
        <input 
          type="text" 
          onChange={this.handleOnChange} 
          style={{ ...styles, ...styles.input }} />
        <button 
          onClick={this.handleOnClick}
          style={{ ...styles, ...styles.button }}>
          Convert hex to rgba
        </button>
        { 
          !!result && 
          <div style={{ textAlign: 'center' }}>
            Converted { color } to { JSON.stringify(result) }
          </div> 
        }
      </Fragment>
    )
  }
}
export default App;

快乐编码=)