Le fondu enchaîné parfait

25

J'ai du mal à décrire ce problème avec des mots, c'est pourquoi j'ai fait une vidéo (45 secondes) pour l'illustrer. Voici un aperçu des questions, veuillez les consulter sur Vimeo: http://vimeo.com/epologee/perfect-crossfade

En utilisant un fondu enchaîné linéaire, l'image résultante aura un «creux» de transparence.  Comment puis-je éviter cela?

La question de la création d'un fondu enchaîné sans faille ou de la dissolution de deux images ou formes m'a été répétée dans un certain nombre de domaines au cours de la dernière décennie. D'abord en montage vidéo, puis en animation Flash et maintenant en programmation iOS. Lorsque vous commencez à le googler, il existe de nombreuses solutions de contournement, mais je veux vraiment résoudre ce problème sans pirater cette fois.

Le résumé:
Quel est le nom de la technique ou de la courbe à appliquer au fondu enchaîné de deux images bitmap semi-transparentes de même couleur, si vous souhaitez que la transparence résultante corresponde à l'original de l'une ou l'autre?

Existe-t-il une fonction (mathématique) pour calculer les valeurs nécessaires de transparence partielle / alpha pendant le fondu?

Existe-t-il des langages de programmation qui ont ces fonctions en tant que préréglage, similaires aux ease in, ease outou ease in outfonctions trouvées dans ActionScript ou Cocoa?

Mise à jour: En plus de la vidéo, j'ai fait un exemple de projet (nécessite Xcode et iOS SDK) et l'ai posté sur github. Il montre la même animation que la vidéo mais cette fois avec des carrés: https://github.com/epologee/StackOverflow-Example-Code

épologée
la source
7
Je n'en sais rien mais +1 pour la vidéo.
sebastiangeiger
Dépend de la façon dont l'opérateur over est implémenté. Voir en.wikipedia.org/wiki/Alpha_channel
artistoex
Je suis d'accord, @artistoex, il y a quelque chose à cela sur l'opérateur, merci pour le lien! Cependant, si la réponse est enterrée quelque part, je ne la vois pas :(
épologée
La représentation mathématique de l'opérateur sur conduit à une équation. Exemple sur opérateur: C = alpha * c1 + (alpha-1) * c2 donne alpha = (C + c2) / (c1 + c2) (C étant le résultat du mélange des deux couleurs c1, c2). Cela signifie que pour ce sur-opérateur, il n'y a pas de fonction qui satisfasse votre condition.
artistoex
Pour C = alpha1 * c1 + alpha2 * c2 (0 <= alpha1, alpha2 <= 1), il existe une telle fonction: alpha1 = (C-alpha2 * c2) / c1.
artistoex

Réponses:

3

J'ai bien peur que ce ne soit pas possible. C'est ainsi que la transparence est calculée lorsque deux objets se superposent: http://en.wikipedia.org/wiki/Alpha_compositing

Compositing alpha

L'un des objets doit avoir une opacité de 1 si vous ne souhaitez pas que la zone de superposition soit visible à travers.

b123400
la source
3

Je ne sais pas quel pourrait être le nom dans le domaine du montage vidéo, mais j'appellerais la courbe une courbe en S ou une courbe sigmoïde . Il devrait être très simple de produire le fondu enchaîné que vous recherchez dans iOS en utilisant la fonction de synchronisation kCAMediaTimingFunctionEaseInEaseOut de Core Animation . Animez simplement la alphapropriété de deux vues dans des directions opposées (une 0-> 1, une 1-> 0) en utilisant cette fonction de synchronisation:

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

Remarque: vous devez vraiment utiliser les méthodes d'animation basées sur les blocs au lieu des méthodes de commodité d'UIView. J'ai utilisé les méthodes d'UIView ci-dessus parce que c'est très facile à comprendre et facile à taper de la mémoire. Cependant, l'utilisation de blocs n'est pas beaucoup plus difficile.

Addendum: si vous n'aimez pas UIViewAnimationEaseInOut, vous pouvez créer votre propre fonction de synchronisation comme décrit dans Timing, Timespaces et CAAnimation . C'est un peu plus avancé que la simple animation illustrée ci-dessus, mais cela vous donne tout le contrôle que vous souhaitez.

Caleb
la source
Sigmoïde! C'est déjà un pas de plus, merci! Le morceau de code que vous fournissez ne fonctionne pas immédiatement, car setAnimationCurve prend un paramètre différent de kCAMediaTimingFunctionEaseInEaseOut. Auriez-vous pu dire UIViewAnimationCurveEaseInOut? Le problème avec cette courbe est cependant le même (creux au milieu), car à tout moment, les deux valeurs alpha dans un simple ajout seront égales 1.0, où comme dans ma courbe ajustée manuellement, elle doit dépasser 1.0pour obtenir les résultats souhaités .
epologee
Je vois maintenant ... vous avez raison au sujet de la constante - j'ai mis à jour le code dans la réponse. J'ai également ajouté un lien vers des documents qui expliquent comment créer vos propres fonctions de synchronisation.
Caleb
Je fais mes animations avec des blocs, mais l'essentiel est le même. Les courbes intégrées ne s'appliquent toujours pas, en raison de leur symétrie, mais l'addendum a ouvert la voie à une fonction CAMediaTiming personnalisée qui correspond à celle que j'ai utilisée dans la vidéo After Effects. Ce qui est troublant, c'est qu'il n'y a pas une courbe sigmoïde qui s'adapte à chaque scénario , différents niveaux de départ d'opacité nécessiteront des positions de Bézier différentes pour se débarrasser de la «baisse». Il doit y avoir quelque chose qui me manque.
epologee
Salut @Caleb, j'ai posté un exemple de projet sur GitHub (voir l'article). Le timing personnalisé est utile, mais si vous modifiez la initialTransparencyvaleur, cela ne sert à rien. Vous ne savez pas quoi essayer ensuite?
epologee
2
Quelques petits morceaux supplémentaires pour aider les recherches Google; les programmeurs graphiques appellent le graphique dont vous parlez un "smoothstep". Les programmeurs hautement mathématiques l'appelleront souvent un "interpolateur hermite". Et une équation simple pour en calculer une sans trigonométrie est: "3t ^ 2 - 2t ^ 3".
Trevor Powell
1

En infographie, ce type de fonction est appelé smoothstep . Lorsqu'il est utilisé pour un fondu enchaîné, il détermine la valeur alpha globale de la composition.

Si les images d'entrée ont un canal alpha, vous devez d'abord vous assurer que l'alpha est prémultiplié . Ensuite, vous pouvez faire la composition du fondu enchaîné directement, en utilisant le smoothstep alphasur chaque canal [ X = A*alpha + B*(1-alpha)], et vous attendre à des résultats raisonnables.

tempête
la source
0

Vous pouvez utiliser la fonction de décroissance exponentielle:

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

Votre graphique ressemble plus à:

Alpha1(time) = sin(time * 0.5 * pi / transitionTime); // fade in
Alpha2(time) = cos(time * 0.5 * pi / transitionTime); // fade out
Danny Varod
la source
Merci @Danny. En fait, l'exécution de l' 1 - Alpha1(time)équation ne prendra pas en charge le creux, car deux images mélangées à 0,5 alpha ne donneront pas lieu à une image composée avec 1,0 alpha. Les courbes personnalisées que j'ai dessinées ne sont pas reflétées verticalement.
epologee
1
Le 1-alpha était pour la décroissance exponentielle, qui je pense est plus appropriée. Pour les fonctions sin / cos bien sûr sin (t) = sqrt (1-sqr (cos (t)), cependant, le calcul de chacune séparément devrait être plus rapide.
Danny Varod
Si le problème était de savoir à quoi pourrait ressembler la fonction d'une courbe similaire, vos calculs sont corrects. Cependant, le problème est de savoir comment gérer le mélange de deux couleurs, par exemple comment obtenir 40% de bleu + 40% de bleu pour obtenir 80% de bleu.
epologee
C'est facile à faire, mais cela entraînerait une saturation mauvaise lorsque la somme des couleurs> 100%.
Danny Varod