css 如何计算产生特定颜色所需的色相旋转?

jm81lzqq  于 2023-01-27  发布在  其他
关注(0)|答案(6)|浏览(204)

我有一个白色的图像,我正在使用作为背景的div,我想颜色匹配的主题主颜色。我知道我可以做:

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

并循环hue-rotate以查找颜色,但是否可以提前计算该值?鉴于指定的十六进制值非常暗,我想我还需要包括invert(%)过滤器。
给定#689d94的十六进制值,我需要做什么数学运算来计算所需的hue-rotateinvert值,以将白色背景图像转换为相同的颜色?

编辑

这是一个div的片段,白色背景的图像被过滤成绿色。这里的技巧是,过滤的是整个div,而不仅仅是图像。如果我在div中输入一些文本,文本的颜色也会变成绿色。
x一个一个一个一个x一个一个二个x

ezykj2lf

ezykj2lf1#

这种情况下的关键是定义一个初始颜色。白色、黑色或任何灰度在技术上都是一种实际的颜色--你不能饱和或旋转它。你必须以某种方式"着色"它,而棕褐色滤镜是唯一一个可以进行某种形式着色的滤镜。
如果你的图像是纯100%红色,那就更容易了。然后你可以直接添加目标度数,并使用HSL作为目标来调整饱和度和亮度。对于白色的起始点,第一步是转换和定义一个中间色,以便我们稍后可以饱和和旋转它。
让我们首先变暗的白色图像和应用棕褐色得到一个"基地"的颜色,我们可以工作:

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

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

rgb(178, 160, 128)

第二步是convert that to HSL color-space,它给出:

hsl(38, 24.5%, 60%);

基色结果

一个三个三个一个

将基色转换为目标色

前两步是静态的,每次我们需要找到目标调整时都会重用其结果(* sepia * 的实际值在SVG Filters规范中定义)。
现在,我们需要计算需要应用于此基色以获得目标色的内容。首先,将目标色(例如问题中给出的#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%)

将这些值转换为filter-string,方法是将其附加到现有的filter,然后将其设置在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表示为浮点,因此可能存在舍入误差,因此实际结果可能不精确,但应该非常接近。

真实的例子

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%);
}
<div></div>
<span style="font:14px sans-serif;padding:7px;color:#fff;background:#689d94">
Target color</span>

可行的备选方案有:

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

cfh9epnr2#

公认的答案是错误的。色调旋转不保留饱和度或亮度,你必须做疯狂的数学来得出正确的值。更简单的方法-这将导致正确的结果-是做一个CSS过滤器引用SVG过滤器。在SVG过滤器中的feColorMatrix原语允许你直接挑选颜色。
以颜色#424242为例,将每个RGB通道值除以#FF,并将它们放入第五列,即颜色矩阵的前三行。在本例中,hex #42是十进制的68,因此除以255(十进制的#FF),您将得到0.257,将其放入第五列,即前三行。

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);
}
<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>
sulc1iza

sulc1iza3#

获得精确匹配的唯一方法是使用SVG颜色矩阵滤镜。

对于RGB颜色#689d94(即rgb(104, 157, 148)),将每个原色的值除以255:

将这些权重放入SVG <filter>矩阵 (前3行中的5列)

<svg xmlns="http://www.w3.org/2000/svg">
  <defs>
    <filter id="689d94" color-interpolation-filters="sRGB">
      <feColorMatrix type="matrix" 
        values="0 0 0 0 0.40784 
                0 0 0 0 0.61569 
                0 0 0 0 0.58039 
                0 0 0 1 0"/>
    </filter>
  </defs>
</svg>

<filter>必须有id(我使用的是RGB十六进制代码689d94),因此我们可以将其用作参考。
由于一些浏览器(例如Firefox)在SVG元素的display属性设置为none时看不到/使用SVG过滤器,并且在HTML代码中包含此SVG元素会不方便地占用一些空间,因此最好的方法是将此SVG转换为纯内联CSS过滤器。
要获取inline filter值,请使用上面列出的SVG代码,通过删除换行符和不必要的空格将其转换为一行,然后将url('data:image/svg+xml,作为前缀,并将前面提到的id作为#689d94')附加:
x一个一个一个一个x一个一个二个x

q7solyqu

q7solyqu4#

十六进制颜色到CSS滤镜转换器

使用此网站计算过滤器:* * 一个

hlswsv35

hlswsv355#

下面是C#中的一个扩展方法(感谢Ωmega提供的知识):

public static class ColorExtensions
{
    public static string ToSvgFilter(this string value)
    {
        Color color = ColorTranslator.FromHtml(value);
        int r = Convert.ToInt16(color.R);
        int g = Convert.ToInt16(color.G);
        int b = Convert.ToInt16(color.B);

        decimal converted_r = (decimal)r / 255;
        decimal converted_g = (decimal)g / 255;
        decimal converted_b = (decimal)b / 255;

        return $"url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\"><defs><filter id=\"{value.Replace("#", "")}\" color-interpolation-filters=\"sRGB\"><feColorMatrix type=\"matrix\" values=\"0 0 0 0 {converted_r} 0 0 0 0 {converted_g} 0 0 0 0 {converted_b} 0 0 0 1 0\"/></filter></defs></svg>{value}')";
    }
}

以下是用法:

protected override async Task OnInitializedAsync()
    {
        _menuItemSvgFilter = "#f20c96".ToSvgFilter();            

        await base.OnInitializedAsync();
    }

剃刀在这里:

<NavLink class="menu-font" href="inboundorders">
     <img src="/img/svg_icon/ICON_ORDER.svg" /> Orders
</NavLink>

我在底部的剃刀上加了这个CSS

<style type="text/css">
.menu-font img 
{
    filter: @_menuItemSvgFilter;
}
</style>
gzszwxb4

gzszwxb46#

如果正在使用SVG,则...
你可以用一些文本编辑器打开svg文件,复制并粘贴到html文件,然后根据需要更改路径颜色。
在下面的示例代码...我只是改变了中心环的路径颜色。希望这有帮助...

var imgg =document.getElementById("path");
        imgg.style="fill:#424242";
<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>

用于背景图像
一个一个二个一个一个一个三个一个一个一个一个一个四个一个

相关问题