如何计算所需的色调旋转以生成特定颜色?

时间:2015-03-13 16:12:10

标签: css css-filters

我有一个白色图像,我用作div的背景,我想要着色以匹配主题主色。我知道我能做到:

filter: sepia() saturate(10000%) hue-rotate(30deg);

并循环显示hue-rotate以查找颜色,但是可以提前计算此值吗?鉴于指定的十六进制值非常暗,我想我也需要包含invert(%)过滤器。

给定十六进制值#689d94我需要做什么数学计算所需的hue-rotateinvert值才能将我的白色背景图像转换为相同的颜色?

修改

这里是div的片段,其中白色背景图片被过滤为绿色。这里的诀窍是,正在过滤的整个div,而不仅仅是图像。如果我要在div中输入一些文字,文字颜色也会变为绿色。



div {
  background:url(http://richard.parnaby-king.co.uk/basket.svg) no-repeat scroll 0 0 transparent;
  background-size:5em;
  width:5em;
  height:5em;
  -webkit-filter: invert(25%) sepia() saturate(100000%) hue-rotate(174deg);
  filter: invert(25%) sepia() saturate(100000%) hue-rotate(174deg);
}

<div>
  </div>
&#13;
&#13;
&#13;

3 个答案:

答案 0 :(得分:66)

这种情况下的关键是定义初始颜色。白色,黑色或任何灰度技术上都是实际颜色 - 您不能使其饱和或旋转。你必须着色&#34;着色&#34;不知何故,棕褐色过滤器是唯一可以进行某种形式着色的过滤器。

如果您的图像纯度为100%红色会更容易。然后你可以直接添加目标度,并使用HSL为目标调整饱和度和亮度。对于白色起点,第一步是转换和定义中间色,以便我们可以在以后饱和并旋转它。

让我们首先使白色图像变暗并使用棕褐色来获得一个&#34;基础&#34;我们可以使用的颜色:

filter: brightness(50%) sepia(1);

这将产生大约的RGB颜色值:

rgb(178, 160, 128)

第二步是convert that to HSL color-space,它给了我们:

hsl(38, 24.5%, 60%);

基色结果

&#13;
&#13;
div {
  background:url(http://richard.parnaby-king.co.uk/basket.svg) no-repeat;
  background-size:5em;
  width:5em;
  height:5em;
  -webkit-filter: brightness(50%) sepia(1);
  filter: brightness(50%) sepia(1);
}
&#13;
<div></div>
&#13;
&#13;
&#13;

将基色转换为目标色

这两个第一步是静态的,每次我们需要找到目标调整时都会重复使用它的结果( sepia 的实际值在SVG Filters specification中定义)。

现在我们需要计算我们需要应用这种基色来获得目标颜色。首先将目标颜色(例如问题中给出的#689d94)转换为HSL:

hsl(170, 21.3%, 51.2%);

然后我们必须计算它们之间的差异。通过简单地从目标中减去基数来计算色调。饱和度和亮度相同,但是当我们假设100%的基值时,我们需要从100%中减去结果,最后得到累积值的差值:

H:  170 - 38             ->  132°
S:  100 + (24.5 - 21.3)  ->  103.2%  (relative to base 100% =  3.2%)
L:  100 + (51.2 - 60.0)  ->   91.2%  (relative to base 100% = -8.8%)

将这些值转换为过滤字符串,方法是将其附加到现有过滤器,然后将其设置在div上:

/*      ------ base color ------  -------  new target -------------------------------*/
filter: brightness(50%) sepia(1)  hue-rotate(132deg) saturate(103.2%) brightness(91.2%);

设置它你可能会做这样的事情,假设已经声明了filter和divElement:

...
filter = "brightness(0.5) sepia(1) hue-rotate(132deg) saturate(103.2%) brightness(91.2%)";
divElement.style.filter = filter;
divElement.style.webkitFilter = filter;

请注意,可能存在舍入错误,因为RGB表示为整数,而HSL是浮点数,因此实际结果可能不准确,但它应该非常接近。

实例

&#13;
&#13;
div {
  background:url(http://richard.parnaby-king.co.uk/basket.svg) no-repeat;
  background-size:5em;
  width:5em;
  height:5em;
  -webkit-filter: 
      brightness(50%) sepia(1) hue-rotate(132deg) saturate(103.2%) brightness(91.2%);
  filter: 
      brightness(50%) sepia(1) hue-rotate(132deg) saturate(103.2%) brightness(91.2%);
}
&#13;
<div></div>
<span style="font:14px sans-serif;padding:7px;color:#fff;background:#689d94">
Target color</span>
&#13;
&#13;
&#13;

可行的替代选择是:

  • 使用已设置的颜色预定义SVG。
  • 直接在JavaScript中使用HSL / RGB,并直接使用颜色修改SVG树,而不是使用过滤器。过滤器在性能上是昂贵的,特别是如果许多链接在这里并且它们是页面的主要部分。并非所有浏览器都支持它们。

答案 1 :(得分:14)

接受的答案是错误的。色调旋转不能保持饱和度或亮度,你必须做疯狂的数学计算才能得出正确的值。更简单的方法 - 这将导致正确的结果 - 是做一个引用SVG过滤器的CSS过滤器。 SVG过滤器中的feColorMatrix原语允许您直接选择颜色 - 就像这样。取你的颜色#424242 - 将每个颜色的十六进制值除以#FF(.257)并将它们放在第五列,即前三行的颜色矩阵中。像这样:

&#13;
&#13;
div {
  background:url(http://richard.parnaby-king.co.uk/basket.svg) no-repeat scroll 0 0 transparent;
  background-size:5em;
  width:5em;
  height:5em;
  -webkit-filter: url(#colorize);
  filter: url(#colorize);
}
&#13;
<div>
  </div>

<svg>
<defs>
<filter id="colorize" color-interpolation-filters="sRGB">
<feColorMatrix type="matrix" values="0 0 0 0 .257
                                 0 0 0 0 .257
                                 0 0 0 0 .257
                                 0 0 0 1 0"/>
 
/filter>
</defs>
</svg>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

如果正在使用svg那么......

您可以打开带有文本编辑器的svg文件并将其粘贴到html文件,然后根据需要更改路径颜色。

在下面的示例代码中......我只是改变了中心环的路径颜色。 希望这会有所帮助..

&#13;
&#13;
        var imgg =document.getElementById("path");
        imgg.style="fill:#424242";
   
&#13;
<html>
<body>
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg id="imgg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 296.838 296.838" style="enable-background:new 0 0 296.838 296.838;" xml:space="preserve" width="512px" height="512px">
<g>
	<path  d="M58.733,64.566L41.763,47.596C14.832,74.526,0,110.333,0,148.419s14.832,73.893,41.763,100.823l16.971-16.971   C36.335,209.874,24,180.095,24,148.419S36.335,86.964,58.733,64.566z" fill="#91DC5A"/>
	<path d="M82.137,81.969c-17.75,17.748-27.525,41.348-27.525,66.45s9.775,48.702,27.525,66.45l16.971-16.971   c-13.218-13.216-20.496-30.788-20.496-49.479s7.278-36.264,20.496-49.48L82.137,81.969z" fill="#91DC5A"/>
	<path d="M255.075,47.596l-16.971,16.971c22.399,22.397,34.733,52.177,34.733,83.853s-12.335,61.455-34.733,83.852l16.971,16.971   c26.931-26.931,41.763-62.737,41.763-100.823S282.006,74.526,255.075,47.596z" fill="#91DC5A"/>
	<path d="M214.701,81.969L197.73,98.939c13.218,13.216,20.496,30.788,20.496,49.48s-7.278,36.264-20.496,49.479l16.971,16.971   c17.75-17.748,27.525-41.348,27.525-66.45S232.451,99.717,214.701,81.969z" fill="#91DC5A"/>
	<path id="path" d="M148.586,114.789c-8.607,0-17.212,3.284-23.78,9.851c-13.131,13.133-13.131,34.424,0,47.559   c6.568,6.566,15.174,9.851,23.78,9.851c8.606,0,17.212-3.284,23.779-9.851c13.131-13.135,13.131-34.426,0-47.559   C165.798,118.073,157.192,114.789,148.586,114.789z M155.395,155.228c-2.454,2.454-5.319,2.821-6.809,2.821   c-1.489,0-4.356-0.367-6.808-2.818c-3.755-3.756-3.755-9.867-0.003-13.619c2.455-2.455,5.321-2.822,6.811-2.822   c1.489,0,4.354,0.367,6.808,2.82C159.147,145.363,159.147,151.475,155.395,155.228z" fill="#91DC5A"/>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>
    
    
</body>
</html>
&#13;
&#13;
&#13;

用于背景图片

&#13;
&#13;
        var myimg='url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 296.838 296.838" style="enable-background:new 0 0 296.838 296.838;" xml:space="preserve" width="512px" height="512px"><g><path  d="M58.733,64.566L41.763,47.596C14.832,74.526,0,110.333,0,148.419s14.832,73.893,41.763,100.823l16.971-16.971   C36.335,209.874,24,180.095,24,148.419S36.335,86.964,58.733,64.566z" fill="#91DC5A"/><path d="M82.137,81.969c-17.75,17.748-27.525,41.348-27.525,66.45s9.775,48.702,27.525,66.45l16.971-16.971   c-13.218-13.216-20.496-30.788-20.496-49.479s7.278-36.264,20.496-49.48L82.137,81.969z" fill="#91DC5A"/><path d="M255.075,47.596l-16.971,16.971c22.399,22.397,34.733,52.177,34.733,83.853s-12.335,61.455-34.733,83.852l16.971,16.971   c26.931-26.931,41.763-62.737,41.763-100.823S282.006,74.526,255.075,47.596z" fill="#91DC5A"/><path d="M214.701,81.969L197.73,98.939c13.218,13.216,20.496,30.788,20.496,49.48s-7.278,36.264-20.496,49.479l16.971,16.971   c17.75-17.748,27.525-41.348,27.525-66.45S232.451,99.717,214.701,81.969z" fill="#91DC5A"/><path d="M148.586,114.789c-8.607,0-17.212,3.284-23.78,9.851c-13.131,13.133-13.131,34.424,0,47.559   c6.568,6.566,15.174,9.851,23.78,9.851c8.606,0,17.212-3.284,23.779-9.851c13.131-13.135,13.131-34.426,0-47.559   C165.798,118.073,157.192,114.789,148.586,114.789z M155.395,155.228c-2.454,2.454-5.319,2.821-6.809,2.821   c-1.489,0-4.356-0.367-6.808-2.818c-3.755-3.756-3.755-9.867-0.003-13.619c2.455-2.455,5.321-2.822,6.811-2.822   c1.489,0,4.354,0.367,6.808,2.82C159.147,145.363,159.147,151.475,155.395,155.228z" fill="#91DC5A"/></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g></svg> \')';
        
        document.getElementById("mydiv").style.backgroundImage =myimg ;  
        
        
        
        //changing color according to theme .. new theme color :#424242
        myimg=myimg.replace(/#91DC5A/g,"#424242");
       document.getElementById("mydiv").style.backgroundImage =myimg ; 
&#13;
             div {

  background-size:5em;
  width:5em;
  height:5em;
  
}
&#13;
<html>
<body>

    
    <div id="mydiv"></div>
<span style="font:14px sans-serif;padding:7px;color:#fff;background:#689d94">
Target color</span>
   
  
    
</body>
</html>
&#13;
&#13;
&#13;