La dissolvenza incrociata perfetta


25

Trovo difficile descrivere questo problema a parole, motivo per cui ho realizzato un video (45 secondi) per illustrarlo. Ecco un'anteprima delle domande, per favore dai un'occhiata su Vimeo: http://vimeo.com/epologee/perfect-crossfade

Usando una dissolvenza incrociata lineare l'immagine risultante avrà un "calo" nella trasparenza.  Come posso impedirlo?

La questione della creazione di una dissolvenza incrociata impeccabile o della dissoluzione di due immagini o forme mi è tornata in molti campi negli ultimi dieci anni. Prima nel montaggio video, poi nell'animazione Flash e ora nella programmazione iOS. Quando inizi a cercare su Google, ci sono molte soluzioni alternative da trovare, ma questa volta voglio davvero risolverlo senza un hack.

Il sommario:
qual è il nome della tecnica o della curva da applicare nella dissolvenza incrociata di due bitmap semitrasparenti dello stesso colore, se si desidera che la trasparenza risultante corrisponda all'originale di una delle due?

Esiste una funzione (matematica) per calcolare i valori di trasparenza / alfa parziali necessari durante la dissolvenza?

Ci sono linguaggi di programmazione che hanno queste funzioni come preselezione, simili alla ease in, ease outo ease in outfunzioni che si trovano in ActionScript o di cacao?

Aggiornamento: oltre al video, ho realizzato un progetto di esempio (richiede Xcode e iOS SDK) e l'ho pubblicato su github. Mostra la stessa animazione del video ma questa volta con i quadrati: https://github.com/epologee/StackOverflow-Example-Code


7
Non ne so nulla ma +1 per il video.
sebastiangeiger,

Dipende da come viene implementato l'operatore over. Vedi en.wikipedia.org/wiki/Alpha_channel
artistoex

Sono d'accordo, @artistoex, c'è qualcosa per quell'operatore, grazie per il link! Tuttavia, se la risposta è sepolta lì da qualche parte, non la vedo :(
epologee

La rappresentazione matematica dell'operatore over porta a un'equazione. Esempio su operatore: C = alfa * c1 + (alfa-1) * c2 restituisce alfa = (C + c2) / (c1 + c2) (C è il risultato della miscelazione dei due colori c1, c2). Ciò significa che per questo operatore, non esiste alcuna funzione che soddisfi le vostre condizioni.
artistoex,

Per C = alpha1 * c1 + alpha2 * c2 (0 <= alpha1, alpha2 <= 1), esiste una tale funzione: alpha1 = (C-alpha2 * c2) / c1.
artistoex,

Risposte:



3

Non so quale potrebbe essere il nome nel regno dell'editing video, ma definirei la curva una curva a S o curva sigmoidea . Dovrebbe essere molto semplice produrre la dissolvenza incrociata che stai cercando in iOS usando la funzione di timing kCAMediaTimingFunctionEaseInEaseOut di Core Animation . Basta animare la alphaproprietà di due viste in direzioni opposte (una 0-> 1, una 1-> 0) usando quella funzione di temporizzazione:

[UIView beginAnimations:@"crossfade" context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
view1.alpha = 0.0;
view2.alpha = 1.0;
[UIView commitAnimations];

Nota: è necessario utilizzare i metodi di animazione basati su blocchi anziché i metodi di convenienza di UIView. Ho usato i metodi di UIView sopra perché è molto facile da capire e facile da scrivere dalla memoria. L'uso dei blocchi non è molto più difficile, però.

Addendum: se non ti piace UIViewAnimationEaseInOut, puoi creare la tua funzione di temporizzazione come descritto in Timing, Timespace e CAAnimation . È un po 'più avanzato della semplice animazione illustrata sopra, ma ti dà tutto il controllo che desideri.


Sigmoid! Questo è già un passo avanti, grazie! Il pezzo di codice fornito non funziona immediatamente, poiché setAnimationCurve accetta un parametro diverso da kCAMediaTimingFunctionEaseInEaseOut. Avresti potuto significare UIViewAnimationCurveEaseInOut? Il problema con quella curva è lo stesso (tuffo nel mezzo), perché in qualsiasi momento, i due valori alfa in una semplice aggiunta saranno uguali 1.0, dove come nella mia curva ottimizzata manualmente deve superare 1.0per ottenere i risultati desiderati .
epologee

Vedo ora ... hai ragione sulla costante - ho aggiornato il codice nella risposta. Ho anche aggiunto un link ai documenti che spiegano come creare le tue funzioni di temporizzazione.
Caleb,

Faccio le mie animazioni con i blocchi, ma l'essenza è la stessa. Le curve integrate non si applicano ancora, a causa della loro simmetria, ma l'addendum ha spianato la strada a una CAMediaTimingFunction personalizzata che corrispondeva a quella che ho usato nel video di After Effects. Il fatto preoccupante è che non esiste una curva sigmoidea che si adatti a ogni scenario , diversi livelli iniziali di opacità richiedono posizioni più bezier diverse per sbarazzarsi del "calo". Deve esserci qualcosa che mi manca.
epologo il

Ciao @Caleb, ho pubblicato un progetto di esempio su GitHub (vedi post). Il tempismo personalizzato è utile, ma se si modifica il initialTransparencyvalore, è inutile. Non avresti idea di cosa provare dopo?
epologo il

2
Qualche altra piccola informazione per aiutare le ricerche di Google; i programmatori grafici chiamano il grafico di cui stai parlando di un "smoothstep". I programmatori altamente matematici lo chiameranno spesso "interpolatore eremita". E una semplice equazione per calcolarne una senza trigonometria è: "3t ^ 2 - 2t ^ 3".
Trevor Powell

1

Nella computer grafica, questo tipo di funzione è chiamata smoothstep . Se utilizzato per dissolvenza incrociata, determina il valore alfa globale per la composizione.

Se le immagini di input hanno un canale alfa, dovresti prima assicurarti che l'alfa sia premoltiplicato . Quindi, è possibile eseguire la composizione con dissolvenza incrociata in modo semplice, utilizzando il passaggio graduale alphasu ciascun canale [ X = A*alpha + B*(1-alpha)] e aspettarsi risultati ragionevoli.


0

È possibile utilizzare la funzione di decadimento esponenziale:

Alpha1(time) = 1 - exp(-time / (0.2 * transitionTime)); // fade in
Alpha2(time) = 1 - Alpha1(time); // fade out

Il tuo grafico è più simile a:

Alpha1(time) = sin(time * 0.5 * pi / transitionTime); // fade in
Alpha2(time) = cos(time * 0.5 * pi / transitionTime); // fade out

Grazie @Danny. In realtà, eseguire l' 1 - Alpha1(time)equazione non si occuperà del calo, perché due immagini alfa 0,5 miste non daranno origine a un'immagine composita con 1,0 alfa. Le curve personalizzate che ho disegnato non sono specchiate verticalmente.
epologo

1
L'1-alfa era per il decadimento esponenziale, che penso sia più adatto. Ovviamente per le funzioni sin / cos sin (t) = sqrt (1-sqr (cos (t)), tuttavia, calcolare ciascuna separatamente dovrebbe essere più veloce.
Danny Varod

Se il problema fosse come potrebbe apparire la funzione di una curva simile, la tua matematica è corretta. Tuttavia, il problema è come gestire la fusione di due colori, ad esempio come ottenere il 40% di blu + 40% di blu per ottenere l'80% di blu.
epologo

Questo è facile da fare, ma si tradurrebbe in una cattiva saturazione quando la somma dei colori> 100%.
Danny Varod,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.