2016-04-24 15 views
5

Ho cercato di generare uno specifico feDisplacementMap e fallire miseramente. Credo che sia perché ho un fondamentale fraintendimento del meccanismo. La specifica SVG 1.1 afferma:Perché il grigio uniforme non è una DisplacementMap neutra?

Questo filtro primitiva utilizza i valori pixel della immagine da ‘in2’ per spostare spazialmente l'immagine da ‘a’. Questa è la trasformazione da eseguire

P '(x, y) < - P (x + scala * (XC (x, y) - .5), y + scala * (YC (x, y) - .5)) dove P (x, y) è l'immagine di ingresso, 'in' e P '(x, y) è la destinazione. XC (x, y) e YC (x, y) sono i valori dei componenti del canale designati da xChannelSelector e yChannelSelector. Ad esempio, per utilizzare il componente R di "in2" per controllare lo spostamento in xe il componente G di Image2 per controllare lo spostamento in y, impostare xChannelSelector su "R" e yChannelSelector su "G".

Con la mia lettura, ciò significa che un'immagine grigia neutra non dovrebbe comportare alcun movimento di pixel di rete. Aka in un filtro con scala = 50, un pixel a 100.100 dovrebbe ottenere il nuovo valore da (100 + 50 * (0,5 - 0,5), 100 + 50 * (0,5-0,5)) = 100,100. Tuttavia, quando provo una scala di grigi, si tratta di mappare i pixel in alto ea sinistra dell'immagine di origine.

<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>

Secondo altre fonti: L'attuale neutro mappa di spostamento dovrebbe essere questa immagine:

enter image description here

+0

Avete un [mcve]? –

risposta

0

Sembra che i browser non seguano le specifiche per questo, e semplicemente duplicano il comportamento di Photoshop nel calcolo del dislocamento.

0

riesco a vedere almeno un bug nel tuo esempio.

Nel proprio <feDisplacementMap> si sta facendo riferimento all'immagine di spostamento (in2) con in2="displacerect". Ma non c'è nessun filtro primitivo con quel valore di risultato. Credo che vuoi dire in2="displaceImage"?

+0

Grazie per la cattura, risolto il problema sopra - ma Chrome ignorava comunque tale riferimento. Il problema generale è sempre lo stesso –

0

Stavo avendo un problema simile. La mia immagine di origine e la mia immagine della mappa di spostamento erano della stessa dimensione, quindi l'immagine di spostamento "neutra" che hai mostrato sopra non potrebbe avere ragione. Doveva essere che il canale rosso e il canale verde avessero gli stessi valori costanti nell'immagine per lo zero spostamento. Non riuscivo a capire perché dovevo usare 188 per uno spostamento da zero pixel invece di 128 come ti aspetteresti. Il blog a http://www.tapper-ware.net/blog/?p=39 offerto il seguente suggerimento che ha risolto il problema per me:

color-interpolation-filters="sRGB" 

codice SVG frammento dell'autore era:

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

Dopo aver specificato lo spazio colore per essere sRGB tutto è cominciato a lavorare come ho previsto.

Problemi correlati