首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用sharp (libvips)实现css/svg对比度滤镜

使用sharp (libvips)实现css/svg对比度滤镜
EN

Stack Overflow用户
提问于 2019-03-24 19:31:01
回答 2查看 520关注 0票数 0

我正在使用libvips在后端转换图像,在前端使用css/svg预览,以节省资源。

我正在努力实现对比度css/svg过滤器函数。

The specification将对比度显示为线性变换,形式为:

代码语言:javascript
复制
out = slope * in + intercept

intercept应该在哪里:

代码语言:javascript
复制
intercept = - (0.5 * slope) + 0.5

这样,我就可以在图像修改的css预览中使用contrast(1.25)

但是,通过JS库sharp在libvips中实现这个线性函数:

代码语言:javascript
复制
sharp.linear(contrast, - (0.5 * contrast) + 0.5)

更深入地研究图像的对比度变化,预期的结果是最高的位置更高,最低的位置更低。这看起来像是与规范的冲突,因为规范应用了线性变换,所以它应该总是乘法和加法,使最高值更高,但也使低值更高一点。

使用线性在夏普(所以在libvips中)来改变对比度输出实际上看起来像一个亮度滤波器,它在css/svg滤波器的规范中是线性变换的形式,而不需要相加

代码语言:javascript
复制
out = slope * in

在我看来,我可能误解了intercept在SVG线性函数中的作用。另外,比较svg和css会显示出不同之处。在css中使用contrast(2)应该模仿svg中的slope = 2intercept = -(0.5 * 2) + 0.5 = -0.5,但在这个小提琴中并非如此:

代码语言:javascript
复制
.svg {
  filter: url(#contrast);
}

.css {
  filter: contrast(2);
}
代码语言:javascript
复制
<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对比度作为线性函数实现,并获得相同的结果?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 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色彩空间设置为颜色。当你这样做的时候,你的图像看起来是一样的。

代码语言:javascript
复制
.svg {
  filter: url(#contrast);
}

.css {
  filter: contrast(2);
}
代码语言:javascript
复制
<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>

票数 1
EN

Stack Overflow用户

发布于 2021-05-02 15:46:43

https://github.com/lovell/sharp/issues/1958

这里有一个来自css的工作公式:

代码语言:javascript
复制
filter: `contrast(${contrast})`

要进行锐化,请执行以下操作:

代码语言:javascript
复制
brightness = 1;
image.linear(brightness * constrast, brightness * (-(128 * contrast) + 128));

不过,我还没有想出如何将brightness集成到其中

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55323334

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档