我正在尝试使用feComponentTransfer函数创建离散梯度:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg x="0" y="0" width="500px" height="120px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>A discrete gradient</title>
<defs>
<linearGradient id="inputImage" gradientUnits="objectBoundingBox" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0" stop-color="black"/>
<stop offset="1" stop-color="white"/>
</linearGradient>
<filter id="discrete" filterUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%" color-interpolation-filters="linearRGB">
<feComponentTransfer>
<feFuncR type="discrete" tableValues=".666667 .6 .533333 .466667 .4 .333333 .266667 .2 .133333 .066667"/>
<feFuncG type="discrete" tableValues=".666667 .6 .533333 .466667 .4 .333333 .266667 .2 .133333 .066667"/>
<feFuncB type="discrete" tableValues=".933333 .866667 .8 .733333 .666667 .6 .533333 .466667 .4 .333333"/>
</feComponentTransfer>
</filter>
</defs>
<rect x="10px" y="10px" width="480px" height="100px" fill="url(#inputImage)" filter="url(#discrete)"/>
</svg>
我希望看到这些颜色:#AAAAEE,#9999DD,#8888CC,#7777BB,#6666AA,#555599,#444488,#333377,#222266,#111155,但显示的是Firefox *这些:#D5D5F7,#CBCBEF,#C1C1E7,#B6B6DE,#AAAAD5,#9C9CCB,#8D8DC1,#7C7CB6,#6666AA,#49499C,它们给出了类似的混合效果,但音调更亮一些。我知道该滤镜的工作是调整亮度,对比度等。但是,我不了解这种情况下滤镜的工作原理。因此,这里的问题是我应该如何计算tableValues中的步骤-在linearRGB颜色空间内-以便准确显示我想要的颜色。
我注意到,大多数显示(输出)颜色的分量值都完全映射到给定范围之外,我想知道-如果我错了,请更正我-这与规范。
由于我不了解这些功能如何在linearRGB色彩空间中工作,因此我决定手动获取所需的颜色。我尝试了随机值,并经过数千次尝试,终于找到了前6种所需颜色(#AAAAEE,#9999DD,#8888CC,#7777BB,#6666AA,#555599)和第九种颜色(#222266)的步骤。对于所需的第七种颜色(#444488,R:68 | 0.266667,G:68 | 0.266667,B:136 | 0.533333),我很容易找到feFuncB步骤,但找不到红色和绿色函数的值来精确输出68 |。 0.266667。因此,最接近所需的#444488为我提供的红色和绿色值为0.058823,它输出的是附近的#454588。我也遇到了同样的问题,即所需的第8种(#333377)和第10种(#111155)颜色,我可以实现的最接近输出分别为#353577和#0D0D55。 这是以一种输出(几乎)我想要的所有颜色的方式编写的tableValues *:
<feFuncR type="discrete" tableValues=".4 .317647 .247058 .184313 .133333 .09 .058823 .0353 .015686 .0039"/> <feFuncG type="discrete" tableValues=".4 .317647 .247058 .184313 .133333 .09 .058823 .0353 .015686 .0039"/> <feFuncB type="discrete" tableValues=".8588 .721568 .603921 .498039 .4 .317647 .247 .184313 .13333 .09"/>
现在,我重复一个问题:是否有一种简便的方法(数学类型,乘数或其他方法)用于显示指定的颜色,而不会浪费时间测试随机小数?
预先感谢
Spyros Andredakis
答案 0 :(得分:0)
在我回答之前,您需要非常注意滴管告诉您的颜色值。如果要在标准sRGB或linearRGB空间中获得特定颜色,请确保将吸管设置为该空间。
也就是说,如果要在linearRGB中进行转换,但是要在sRGB中获得特定颜色作为结果,则需要以linearRGB术语指定等效的目标sRGB颜色。您可以使用伽玛校正公式来完成此操作。
例如,如果您希望渐变中的第一个颜色是sRGB中的#AAAAEE,则必须对数组输入进行以下校正(十进制):
linearRGB中的颜色=((sRGB + 0.055中的颜色)/1.055)^ 2.4
例如,您的组件传输数组中的第一个R / G / B值应为
R:0.402 =((.6667 + 0.055)/1.055)^ 2.4
G:0.402 =((.6667 + 0.055)/1.055)^ 2.4
B:0.855 =((.9333 + 0.055)/1.055)^ 2.4
此公式通常不能精确到100%-当sRGB单位值小于0.04045(L = S / 12.92)时,您需要使用其他公式。但是您所有的目标值都高于0.04,因此我们无需担心。
完整结果:
<svg x="0" y="0" width="500px" height="120px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>A discrete gradient</title>
<defs>
<linearGradient id="inputImage" gradientUnits="objectBoundingBox" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0" stop-color="black"/>
<stop offset="1" stop-color="white"/>
</linearGradient>
<filter id="discrete" filterUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%">
<feComponentTransfer>
<feFuncR type="discrete" tableValues="0.4020 0.3185 0.2462 0.1845 0.1329 0.0908 0.0578 0.0331 0.0160 0.0056"/>
<feFuncG type="discrete" tableValues="0.4020 0.3185 0.2462 0.1845 0.1329 0.0908 0.0578 0.0331 0.0160 0.0056"/>
<feFuncB type="discrete" tableValues="0.8550 0.7231 0.6038 0.4969 0.4020 0.3185 0.2462 0.1845 0.1329 0.0908"/>
</feComponentTransfer>
</feComponentTransfer>
</filter>
</defs>
<rect x="10px" y="10px" width="480px" height="100px" fill="url(#inputImage)" filter="url(#discrete)"/>
</svg>