我正在使用libvips在后端转换图像,在前端使用css/svg预览,以节省资源。
我正在努力实现对比度css/svg过滤器函数。
The specification将对比度显示为线性变换,形式为:
out = slope * in + interceptintercept应该在哪里:
intercept = - (0.5 * slope) + 0.5这样,我就可以在图像修改的css预览中使用contrast(1.25)。
但是,通过JS库sharp在libvips中实现这个线性函数:
sharp.linear(contrast, - (0.5 * contrast) + 0.5)更深入地研究图像的对比度变化,预期的结果是最高的位置更高,最低的位置更低。这看起来像是与规范的冲突,因为规范应用了线性变换,所以它应该总是乘法和加法,使最高值更高,但也使低值更高一点。
使用线性在夏普(所以在libvips中)来改变对比度输出实际上看起来像一个亮度滤波器,它在css/svg滤波器的规范中是线性变换的形式,而不需要相加
out = slope * in在我看来,我可能误解了intercept在SVG线性函数中的作用。另外,比较svg和css会显示出不同之处。在css中使用contrast(2)应该模仿svg中的slope = 2和intercept = -(0.5 * 2) + 0.5 = -0.5,但在这个小提琴中并非如此:
.svg {
filter: url(#contrast);
}
.css {
filter: contrast(2);
}<img src="https://dev-cdn.swbpg.com/o/g/1515254671.jpeg" width="300">
<img class="svg" src="https://dev-cdn.swbpg.com/o/g/1515254671.jpeg" width="300">
<img class="css" src="https://dev-cdn.swbpg.com/o/g/1515254671.jpeg" width="300">
<svg>
<filter id="contrast">
<feComponentTransfer>
<feFuncR type="linear" slope="2" intercept="-0.5"/>
<feFuncG type="linear" slope="2" intercept="-0.5"/>
<feFuncB type="linear" slope="2" intercept="-0.5"/>
</feComponentTransfer>
</filter>
</svg>
您可以清楚地看到,使用svg过滤器的第二个图像与使用css过滤器的第三个图像看起来不同。
我对过滤器的理解是完全错误的吗?我希望有一些地方可以将乘法转化为低点的除法。
如何将不同环境下的css对比度作为线性函数实现,并获得相同的结果?
发布于 2019-03-26 13:40:40
您的直觉不正确:)对于小于0.5的输入值-公式降低亮度-为什么?让我们将对比度值设为2,输入值设为0.4
输出= 2*0.4 - (0.5 *2) + 0.5
输出= 0.8 -1+ 0.5
输出= 0.3
如您所见,当输入小于0.5时,输出将始终小于输入,因为坡度分量和截距的第一个(负)分量的总和将等于对比度乘以输入和0.5之间的差值
这是单一化值的公式结果(floored和ceilinged on 0/1)。

另外,CSS过滤器默认使用sRGB颜色空间。SVG过滤器使用linearRGB。您需要通过向SVG元素添加attribute: sRGB -interpolation-filters=“sRGB”将svg filter色彩空间设置为颜色。当你这样做的时候,你的图像看起来是一样的。
.svg {
filter: url(#contrast);
}
.css {
filter: contrast(2);
}<img src="https://dev-cdn.swbpg.com/o/g/1515254671.jpeg" width="300">
<img class="svg" src="https://dev-cdn.swbpg.com/o/g/1515254671.jpeg" width="300">
<img class="css" src="https://dev-cdn.swbpg.com/o/g/1515254671.jpeg" width="300">
<svg color-interpolation-filters="sRGB">
<filter id="contrast">
<feComponentTransfer>
<feFuncR type="linear" slope="2" intercept="-0.5"/>
<feFuncG type="linear" slope="2" intercept="-0.5"/>
<feFuncB type="linear" slope="2" intercept="-0.5"/>
</feComponentTransfer>
</filter>
</svg>
发布于 2021-05-02 15:46:43
https://github.com/lovell/sharp/issues/1958
这里有一个来自css的工作公式:
filter: `contrast(${contrast})`要进行锐化,请执行以下操作:
brightness = 1;
image.linear(brightness * constrast, brightness * (-(128 * contrast) + 128));不过,我还没有想出如何将brightness集成到其中
https://stackoverflow.com/questions/55323334
复制相似问题