是否可以拍摄一张 IMG 图片并将一种确切的颜色替换为另一种颜色,例如将 #fff 替换为 #000,同时保持所有其他颜色不变?也许 SVG 滤镜的颜色矩阵可以提供帮助?
最佳答案
这对于 Canvas 来说是微不足道的。也可以使用 SVG 来完成,但它很复杂。以下方法适用于传统的完全不透明图像。首先,使用长 ComponentTransfer 将每个 channel 中的每个不匹配颜色值转换为 0,并将每个匹配颜色值转换为 1(256 个成员 tableValues 数组中唯一“1”的索引应与您的 r、g 和 b 匹配)替换值)。然后,使用颜色矩阵将除生成的白色像素之外的所有内容的 Alpha 值归零。您可以使用结果作为带有目标颜色 feFlood 的蒙版,并将结果合成在原始图形之上。例如,以下代码将特定颜色 - rgb(87, 78, 29) - 替换为蓝色。
<svg width="600px" height="600px" viewBox="0 0 600 600">
<defs>
<filter id="color-replace" color-interpolation-filters="sRGB">
<!-- Replace rgb(87,78,29) with blue. -->
<feComponentTransfer >
<feFuncR type="discrete" tableValues="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"/>
<feFuncG type="discrete" tableValues="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"/>
<feFuncB type="discrete" tableValues="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"/>
</feComponentTransfer>
<feColorMatrix type="matrix" values="1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
1 1 1 1 -3" result="selectedColor"/>
<feFlood flood-color="blue"/>
<feComposite operator="in" in2="selectedColor"/>
<feComposite operator="over" in2="SourceGraphic"/>
</filter>
</defs>
<g filter="url(#color-replace)">
<rect x="50" y="50" height="100" width="100" fill="rgb(86,77,28)"/>
<rect x="250" y="50" height="100" width="100" fill="rgb(86,77,29)"/>
<rect x="450" y="50" height="100" width="100" fill="rgb(86,78,29)"/>
<rect x="50" y="250" height="100" width="100" fill="rgb(87,77,29)"/>
<rect x="250" y="250" height="100" width="100" fill="rgb(87,78,29)"/>
<rect x="450" y="250" height="100" width="100" fill="rgb(87,78,30)"/>
<rect x="50" y="450" height="100" width="100" fill="rgb(88,78,30)"/>
<rect x="250" y="450" height="100" width="100" fill="rgb(88,79,29)"/>
<rect x="450" y="450" height="100" width="100" fill="rgb(88,79,30)"/>
</g>
</svg>
更新:
如果您想用不透明度小于 1 的颜色替换原始颜色,那么您需要采取额外的步骤 - 在替换之前删除选定的颜色。您可以通过这种方式扩展过滤器来实现此目的。
<--snipping first half of filter -->
<feColorMatrix type="matrix" values="1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
1 1 1 1 -3" result="selectedColor"/>
<feComposite operator="out" in="SourceGraphic" result="notSelectedColor"/>
<feFlood flood-color="blue" flood-opacity="0.5"/>
<feComposite operator="in" in2="selectedColor"/>
<feComposite operator="over" in2="notSelectedColor"/>
</filter>
关于canvas - 使用 SVG 滤镜替换一种颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41639049/