2016-04-24 7 views
5

Ich habe versucht, eine bestimmte feDisplacementMap zu generieren und kläglich scheitern. Ich glaube, es liegt daran, dass ich ein fundamentales Missverständnis über den Mechanismus habe. Die SVG 1.1 Spezifikation sagt:Warum ist ein einheitliches Grau keine neutrale DisplacementMap?

Diese Filter primitive die Pixelwerte aus dem Bild von ‚in2‘ verwendet räumlich um das Bild von ‚in‘ zu verdrängen. Dies ist die Transformation durchgeführt werden:

P '(x, y) < - P (x + * Skala (XC (x, y) - 0,5) + y * Skala (YC (x, y) - .5)) Dabei ist P (x, y) das Eingabebild, 'in' und P '(x, y) ist das Ziel. XC (x, y) und YC (x, y) sind die Komponentenwerte des Kanals, der von xChannelSelector und yChannelSelector als bezeichnet wird. Um beispielsweise die R-Komponente von 'in2' zur Steuerung der Verschiebung in x und die G-Komponente von Image2 zur Steuerung der Verschiebung in y zu verwenden, setzen Sie xChannelSelector auf "R" und yChannelSelector auf "G".

Durch meine Lesung bedeutet dies, dass ein neutrales Graubild keine Netto-Pixelbewegung ergeben sollte. Aka in einem Filter mit Skala = 50, ein Pixel bei 100,100 sollte seinen neuen Wert von (100 + 50 * (0,5 - 0,5), 100 + 50 * (0,5-0,5)) = 100,100 erhalten. Wenn ich jedoch eine Graustufe versuche, werden die Pixel nach oben und links vom Quellbild dargestellt.

<svg width="800px" height="600px" > 
 
    
 
    <defs> 
 
    <g id="displacerect"> 
 
    <rect x="50" y="50" width="300" height="300" fill="rgb(127, 127, 127)"/> 
 
    <rect x="90" y="90" width="50" height="50" fill="red"> 
 
     </rect> 
 
    </g> 
 
    
 
    
 
     <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%"> 
 
     <stop offset="0%" stop-color="rgb(255,255,0)" stop-opacity="1" /> 
 
     <stop offset="100%"stop-color="rgb(255,0,0)" stop-opacity="1" /> 
 
    </linearGradient> 
 
    
 
    <filter id="displaceME" x="0%" y="0%" width="100%" height="100%"> 
 
    <feImage xlink:href="#displacerect" result="displaceImage"/> 
 
    <feDisplacementMap scale="125" xChannelSelector="R" yChannelSelector="G" in="SourceGraphic" in2="displaceImage"/> 
 

 
    
 
    </filter> 
 
    
 
    </defs> 
 
    
 
    <g filter="url(#displaceME)"> 
 
    <rect x="50" y="50" width="300" height="300" fill="url(#grad1)"/> 
 
    </g> 
 
    
 
    <use xlink:href="#displacerect" x="400"/> 
 
    
 
    
 
    
 
</svg>

Nach anderen Quellen: die IST-Verlagerungs Karte sollte dieses Bild sein:

enter image description here

+0

Haben Sie eine [MCVE]? –

Antwort

0

Es sieht so aus, als würden Browser die Spezifikation nicht befolgen und das Verhalten von Photoshop bei der Berechnung der Verschiebung einfach duplizieren.

0

Ich kann zumindest einen Fehler in Ihrem Beispiel sehen.

In Ihrer <feDisplacementMap> beziehen Sie sich auf Ihre Verschiebung Bild (in2) mit in2="displacerect". Aber es gibt kein Filter-Primitiv mit diesem Ergebniswert. Ich glaube du meinst in2="displaceImage"?

+0

Danke für den Haken, diesen Fehler oben behoben - aber Chrome ignorierte diese Referenz trotzdem. Das Gesamtproblem ist immer noch das gleiche –

0

Ich hatte ein ähnliches Problem. Mein Quellbild und mein Verschiebungs-Kartenbild hatten die gleiche Größe, so dass das oben gezeigte "neutrale" Verschiebungsbild möglicherweise nicht richtig sein konnte. Es musste sein, dass der rote Kanal und der grüne Kanal die gleichen konstanten Werte über das Bild für die Nullverschiebung hatten. Ich konnte nicht verstehen, warum ich 188 für eine Null-Pixel-Verschiebung anstelle von 128 verwenden musste, wie Sie es erwarten würden. Der Blog unter http://www.tapper-ware.net/blog/?p=39 bot den folgenden Hinweis, dass das Problem für mich gelöst:

color-interpolation-filters="sRGB" 

SVG-Code-Schnipsel des Autors war:

<svg:filter 
id="myFilterId" 
color-interpolation-filters="sRGB" 
filterUnits="userSpaceOnUse" 
x="0" y="0" width="768" height="512"> 
</svg:filter> 

Nach dem Farbraum spezifiziert zu sein sRGB alles begann arbeiten, wie ich erwartet.

Verwandte Themen