【问题标题】:Get a color component from an rgb string in Javascript?从 Javascript 中的 rgb 字符串中获取颜色分量?
【发布时间】:2012-06-13 19:38:14
【问题描述】:

我正在使用 Javascript 和 Canvas 制作一个绘画应用程序,并使用这种格式的字符串来指定所选颜色:

"rgb(255,0,0)"

因为画布上下文 fillStyle 属性接受该格式的字符串。

但是,我现在需要从这个字符串中获取单个组件,并且想知道是否有一种方法可以在不进行混乱的字符串操作的情况下做到这一点。可能有一些内置方法将该字符串转换为某种颜色对象,然后访问其 r、g 和 b 组件?

谢谢。

【问题讨论】:

  • 我不知道,但我很想被证明是错误的。

标签: javascript html canvas colors


【解决方案1】:

注意 - 我们都支持 regex 吃了我的大脑,踢了我的狗 的态度,但 regex 版本似乎是更好的方法。我的想法。看看吧。

非正则表达式方法:

var rgb = 'rgb(200, 12, 53)';

rgb = rgb.substring(4, rgb.length-1)
         .replace(/ /g, '')
         .split(',');

console.log(rgb);

http://jsfiddle.net/userdude/Fg9Ba/

输出:

["200", "12", "53"]

或者...一个非常简单的正则表达式:

编辑:糟糕,由于某种原因,正则表达式中有一个i

var rgb = 'rgb(200, 12, 53)';

rgb = rgb.replace(/[^\d,]/g, '').split(',');

console.log(rgb);

http://jsfiddle.net/userdude/Fg9Ba/2

【讨论】:

  • nice... 只需要在正则表达式中添加一个句点来说明 rgba 浮点值:rgb.replace(/[^\d,.]/g, '').split(' ,')
  • @bob 的评论很到位,为 RGBA 数组返回 Array [ "255", "255", "255", "0.5" ]
  • 对于 HSL 也可以添加 %:/[^\d,.%]/g
【解决方案2】:

更简单的方法..

    var rgb = 'rgb(200, 12, 53)'.match(/\d+/g);
    console.log(rgb);  

这里的输出为

    ["200", "12", "53"]

" 简单总是美丽的 !" :)

【讨论】:

  • 当存在 Alpha 通道时失败,例如rgba(1, 1, 1, 0.6),在这种情况下它返回["1", "1", "1", "0", "6"]
  • 是的,但是如果您只使用数组中的前三个值,您将始终获得 R、G、B 值
【解决方案3】:

我的版本采用HEXRGBRGBa 字符串作为参数,不使用正则表达式,并返回一个具有红色、绿色和蓝色(以及RGBa 的alpha)数字值的对象。

var RGBvalues = (function() {

    var _hex2dec = function(v) {
        return parseInt(v, 16)
    };

    var _splitHEX = function(hex) {
        var c;
        if (hex.length === 4) {
            c = (hex.replace('#','')).split('');
            return {
                r: _hex2dec((c[0] + c[0])),
                g: _hex2dec((c[1] + c[1])),
                b: _hex2dec((c[2] + c[2]))
            };
        } else {
             return {
                r: _hex2dec(hex.slice(1,3)),
                g: _hex2dec(hex.slice(3,5)),
                b: _hex2dec(hex.slice(5))
            };
        }
    };

    var _splitRGB = function(rgb) {
        var c = (rgb.slice(rgb.indexOf('(')+1, rgb.indexOf(')'))).split(',');
        var flag = false, obj;
        c = c.map(function(n,i) {
            return (i !== 3) ? parseInt(n, 10) : flag = true, parseFloat(n);
        });
        obj = {
            r: c[0],
            g: c[1],
            b: c[2]
        };
        if (flag) obj.a = c[3];
        return obj;
    };

    var color = function(col) {
        var slc = col.slice(0,1);
        if (slc === '#') {
            return _splitHEX(col);
        } else if (slc.toLowerCase() === 'r') {
            return _splitRGB(col);
        } else {
            console.log('!Ooops! RGBvalues.color('+col+') : HEX, RGB, or RGBa strings only');
        }
    };

    return {
        color: color
    };
}());

console.debug(RGBvalues.color('rgb(52, 86, 120)'));
  //-> { r: 52, g: 86, b: 120 }
console.debug(RGBvalues.color('#345678'));
  //-> { r: 52, g: 86, b: 120 }
console.debug(RGBvalues.color('rgba(52, 86, 120, 0.67)'));
  //-> { r: 52, g: 86, b: 120, a: 0.67 }
console.debug(RGBvalues.color('#357'));
  //-> { r: 51, g: 85, b: 119 }

可能对某人有用。 :)

【讨论】:

    【解决方案4】:

    使用像the xolor library这样的颜色库怎么样:

    xolor("rgb(200,100,40)").r // returns the red part
    

    【讨论】:

    • ...使用 29kb 库来完成可以通过 ¹/₆₆₃ʳᵈ 的膨胀完成的任务(单个 line 代码)只是 错误这么多关卡。
    • 它只有 13kb 未压缩。缩小和压缩后为 6kb。很抱歉,我建议任何人使用模块化设计而不是滚动他们自己的容易产生垃圾错误的正则表达式。我在想什么?
    【解决方案5】:

    即使您确定颜色将采用 rgb 格式,而不是 rgbA、十六进制、颜色名称或 hsl,您仍然可以使用 'rgb(25%,55%,100%)'。

    function Rgb(rgb){
        if(!(this instanceof Rgb)) return new Rgb(rgb);
        var c= rgb.match(/\d+(\.\d+)?%?/g);
        if(c){
            c= c.map(function(itm){
                if(itm.indexOf('%')!= -1) itm= parseFloat(itm)*2.55;
                return parseInt(itm);
            });
        }
        this.r= c[0];
        this.g= c[1];
        this.b= c[2];
    }
    

    var c= Rgb('rgb(10%,25%,55%)'); 警报([c.r,c.g,c.b])

    注意-如果你使用画布,你有地图。

    否则-

    Array.prototype.map=Array.prototype.map || function(fun, scope){
            var T= this, L= T.length, A= Array(L), i= 0;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in T){
                        A[i]= fun.call(scope, T[i], i, T);
                    }
                    ++i;
                }
                return A;
            }
        }
    

    【讨论】:

    • rgb 值中包含浮点数是不合法的,对吧?我想如果你验证了字符串,你可以测试并拒绝它和其他颜色格式,比如rgba
    【解决方案6】:

    如果您对 RGB(A) 作为数值感兴趣:

    const [r,g,b,a] = "rgb(50,205,50)".match(/\d+/g).map(Number);
    

    如果字符串中只有 3 个数字,请注意 alpha (a) 未定义!

    【讨论】:

    • 这不适用于基于十进制的 alpha 值
    【解决方案7】:

    对于使用颜色选择器的人,此库还允许转换多种格式的颜色:https://tovic.github.io/color-picker/

    CP.RGB2HEX([255, 255, 255])
    

    【讨论】:

      【解决方案8】:

      Mozilla Fathom 中实现了一种(某种)简单的正则表达式解决方案,它也可以识别 alpha:

      /**
       * Return the extracted [r, g, b, a] values from a string like "rgba(0, 5, 255, 0.8)",
       * and scale them to 0..1. If no alpha is specified, return undefined for it.
       */
      export function rgbaFromString(str) {
          const m = str.match(/^rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)$/i);
          if (m) {
              return [m[1] / 255, m[2] / 255, m[3] / 255, m[4] === undefined ? undefined : parseFloat(m[4])];
          } else {
              throw new Error('Color ' + str + ' did not match pattern rgb[a](r, g, b[, a]).');
          }
      }
      

      【讨论】:

        【解决方案9】:

        长但适用于 RGB 字符串 abd RGBA 字符串到数字数组。

        function rgbStringToArray(rgbString){
                let arr=rgbString.replace(/ /g,'').slice(
                    rgbString.indexOf("(") + 1,
                    rgbString.indexOf(")")
                ).split(",");
                for(let i=0;i<arr.length;i++){
                    if(arr.length-1===i && arr.length===4) 
                        arr[i]=parseFloat(arr[i]); 
                    else 
                        arr[i]=parseInt(arr[i]);
                }
                return arr;
            }
        

        【讨论】:

          猜你喜欢
          • 2016-05-01
          • 1970-01-01
          • 2016-10-14
          • 1970-01-01
          • 2017-11-30
          • 2014-06-21
          • 1970-01-01
          • 2011-04-01
          • 2014-04-25
          相关资源
          最近更新 更多