I try to generate SVGs that are composed of filters and I would like to have exactly the same rendering when the same image is resized (with ratio kept).
I use two filters: feTurbulence and feDisplacementMap
My problem is that I can't get the same rendering when the same image is resized.
I was hoping that it would be enough to change the values of the attributes of the effects proportionally but it doesn't work.
In this case, if I change the "scale" and "baseFrequency" values proportionally it doesn't work.
How can I calculate the values of "scale" and "baseFrequency" to get exactly the same rendering whatever the size of the image?
IMAGE 1 - 300x132px
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" height="132">
<defs>
<filter id="filter1" x="0%" y="0%" width="100%" height="100%" filterUnits="userSpaceOnUse">
<feTurbulence baseFrequency="0.05" result="NOISE" type="turbulence" />
<feDisplacementMap in="SourceGraphic" in2="NOISE" result="RESULT" scale="10" xChannelSelector="R" yChannelSelector="R"></feDisplacementMap>
</filter>
</defs>
<image x="0" y="0" width="300" height="132" href="https://i.stack.imgur.com/osUI3.png" filter="url(#filter1)"></image>
</svg>
RESULT 1:
IMAGE 2 - 600x264px (x2)
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="600" height="264">
<defs>
<filter id="filter2" x="0%" y="0%" width="100%" height="100%" filterUnits="userSpaceOnUse">
<feTurbulence baseFrequency="0.05" result="NOISE" type="turbulence" />
<feDisplacementMap in="SourceGraphic" in2="NOISE" result="RESULT" scale="10" xChannelSelector="R" yChannelSelector="R"></feDisplacementMap>
</filter>
</defs>
<image x="0" y="0" width="600" height="264" href="https://i.stack.imgur.com/MNepH.png" filter="url(#filter2)"></image>
</svg>
RESULT 2:
We can see that the effect is different on RESULT 1 and RESULT 2.
The example is on this page: https://jsfiddle.net/qbvp8x1r/
CodePudding user response:
If you use the same viewBox for both SVGs you get the same result. The viewBox defines the "inner coordinate system" for the image.
In this example I moved the filter to a separate SVG to show that it can be reused. To make the image fit in the SVG I set the width to 100%. So, everything is relative except the viewBox.
<svg width="0" height="0" xmlns="http://www.w3.org/2000/svg">
<defs>
<filter id="filter1" x="0%" y="0%" width="100%" height="100%" filterUnits="userSpaceOnUse">
<feTurbulence baseFrequency="0.05" result="NOISE" type="turbulence" />
<feDisplacementMap in="SourceGraphic" in2="NOISE" result="RESULT" scale="10" xChannelSelector="R" yChannelSelector="R"></feDisplacementMap>
</filter>
</defs>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="300"
viewBox="0 0 300 132">
<image width="100%" href="https://i.stack.imgur.com/osUI3.png"
filter="url(#filter1)" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="600"
viewBox="0 0 300 132">
<image width="100%" href="https://i.stack.imgur.com/SS7N6.png"
filter="url(#filter1)" />
</svg>