Die perfekte Überblendung


25

Ich finde es schwierig, dieses Problem in Worten zu beschreiben, weshalb ich ein Video (45 Sekunden) gemacht habe, um es zu veranschaulichen. Hier ist eine Vorschau der Fragen, bitte schauen Sie sie sich auf Vimeo an: http://vimeo.com/epologee/perfect-crossfade

Bei Verwendung einer linearen Überblendung weist das resultierende Bild einen Transparenzabfall auf.  Wie kann ich das verhindern?

Das Problem, eine makellose Überblendung oder Überblendung von zwei Bildern oder Formen zu erstellen, tauchte in den letzten zehn Jahren in einer Reihe von Bereichen immer wieder auf. Zuerst in der Videobearbeitung, dann in der Flash-Animation und jetzt in der iOS-Programmierung. Wenn Sie anfangen zu googeln, gibt es viele Problemumgehungen, aber diesmal möchte ich das wirklich ohne einen Hack lösen.

Die Zusammenfassung:
Wie lautet der Name der Technik oder Kurve, die beim Überblenden von zwei halbtransparenten, gleichfarbigen Bitmaps angewendet werden soll, wenn die resultierende Transparenz mit dem Original einer der beiden übereinstimmen soll?

Gibt es eine (mathematische) Funktion, um die notwendigen partiellen Transparenz- / Alpha-Werte während der Überblendung zu berechnen?

Gibt es Programmiersprachen , die diese Funktionen als Preset, ähnlich wie die haben ease in, ease outoder ease in outin Actionscript oder Kakao gefunden Funktionen?

Update: Zusätzlich zum Video habe ich ein Beispielprojekt erstellt (erfordert Xcode und iOS SDK) und es auf github gepostet. Es zeigt die gleiche Animation wie das Video, diesmal jedoch mit Quadraten: https://github.com/epologee/StackOverflow-Example-Code


7
Ich weiß nichts darüber, aber +1 für das Video.
Sebastiangeiger

Hängt davon ab, wie der over-Operator implementiert ist. Siehe en.wikipedia.org/wiki/Alpha_channel
artistoex

Ich stimme zu, @artistoex, da ist etwas über Operator, danke für den Link! Wenn die Antwort jedoch irgendwo dort vergraben ist, sehe ich sie nicht :(
Epolog

Die mathematische Darstellung des Over-Operators führt zu einer Gleichung. Beispiel über Operator: C = alpha * c1 + (alpha-1) * c2 ergibt alpha = (C + c2) / (c1 + c2) (C ist das Ergebnis des Mischens der beiden Farben c1, c2). Dies bedeutet, dass für diesen Über-Operator keine Funktion vorhanden ist, die Ihre Bedingung erfüllt.
artistoex

Für C = alpha1 * c1 + alpha2 * c2 (0 <= alpha1, alpha2 <= 1) gibt es eine solche Funktion: alpha1 = (C-alpha2 * c2) / c1.
artistoex

Antworten:



3

Ich weiß nicht, wie der Name im Bereich der Videobearbeitung lauten könnte, aber ich würde die Kurve als S-Kurve oder Sigmoid-Kurve bezeichnen . Mit der Timing-Funktion kCAMediaTimingFunctionEaseInEaseOut von Core Animation sollte es sehr einfach sein, die gewünschte Überblendung in iOS zu erstellen . Animieren Sie einfach die alphaEigenschaft von zwei Ansichten in entgegengesetzten Richtungen (eine 0-> 1, eine 1-> 0) mit dieser Zeitfunktion:

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

Hinweis: Sie sollten wirklich die blockbasierten Animationsmethoden anstelle der praktischen Methoden von UIView verwenden. Ich habe die oben beschriebenen Methoden von UIView verwendet, da sie sehr einfach zu verstehen und aus dem Speicher zu tippen sind. Die Verwendung von Blöcken ist jedoch nicht viel schwieriger.

Nachtrag: Wenn Ihnen UIViewAnimationEaseInOut nicht gefällt, können Sie Ihre eigene Timing-Funktion erstellen, wie in Timing, Timespaces und CAAnimation beschrieben . Das ist etwas fortgeschrittener als die oben abgebildete einfache Animation, bietet Ihnen jedoch alle gewünschten Steuerungsmöglichkeiten.


Sigmoid! Das ist schon einen Schritt näher, danke! Der von Ihnen angegebene Code funktioniert nicht sofort, da setAnimationCurve einen anderen Parameter als verwendet kCAMediaTimingFunctionEaseInEaseOut. Könnten Sie gemeint haben UIViewAnimationCurveEaseInOut? Das Problem mit dieser Kurve ist jedoch dasselbe (Sprung in die Mitte), da zu jedem Zeitpunkt die beiden Alpha-Werte in einer einfachen Addition gleich sind 1.0, wobei sie wie bei meiner manuell optimierten Kurve überschritten werden müssen 1.0, um die gewünschten Ergebnisse zu erzielen .
Epolog

Ich verstehe jetzt ... Sie haben Recht mit der Konstante - ich habe den Code in der Antwort aktualisiert. Ich habe auch einen Link zu Dokumenten hinzugefügt, die erklären, wie Sie Ihre eigenen Timing-Funktionen erstellen.
Caleb

Ich mache meine Animationen mit Blöcken, aber das Wesentliche ist dasselbe. Die eingebauten Kurven sind aufgrund ihrer Symmetrie immer noch nicht gültig, aber das Addendum ebnete den Weg zu einer benutzerdefinierten CAMediaTimingFunction, die der im After Effects-Video verwendeten Funktion entsprach. Beunruhigend ist, dass es nicht eine Sigmoidkurve gibt, die für jedes Szenario geeignet ist. Unterschiedliche Opazitätsniveaus erfordern unterschiedliche Bezierpositionen, um das "Eintauchen" zu beseitigen. Es muss etwas geben, was ich vermisse.
Epolog

Hallo @Caleb, ich habe ein Beispielprojekt auf GitHub gepostet (siehe Beitrag). Das benutzerdefinierte Timing ist hilfreich, aber wenn Sie den initialTransparencyWert ändern , kann es nicht verwendet werden. Sie hätten keine Ahnung, was Sie als Nächstes versuchen sollten?
Epolog

2
Noch ein paar Kleinigkeiten für die Google-Suche. Grafikprogrammierer nennen die Grafik, von der Sie sprechen, "Smoothstep". Sehr mathematische Programmierer nennen es oft einen "Einsiedler-Interpolator". Und eine einfache Gleichung, um eine ohne Trigonometrie zu berechnen, lautet: "3t ^ 2 - 2t ^ 3".
Trevor Powell

1

In der Computergrafik wird diese Art von Funktion als Smoothstep bezeichnet . Beim Überblenden wird der globale Alpha-Wert für die Komposition bestimmt.

Wenn die Eingabebilder einen Alphakanal haben, sollten Sie zuerst sicherstellen, dass das Alpha vorvervielfacht ist . Dann können Sie die Überblendungskomposition mit dem Smoothstep alphaauf jedem Kanal [ X = A*alpha + B*(1-alpha)] direkt ausführen und vernünftige Ergebnisse erwarten.


0

Sie können die exponentielle Abklingfunktion verwenden:

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

Ihr Graph sieht eher so aus:

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

Vielen Dank @Danny. Tatsächlich 1 - Alpha1(time)kümmert sich das Durchführen der Gleichung nicht um das Eintauchen, da zwei gemischte 0,5-Alpha-Bilder nicht zu einem zusammengesetzten Bild mit 1,0 Alpha führen. Die benutzerdefinierten Kurven, die ich gezeichnet habe, werden nicht vertikal gespiegelt.
Epolog

1
Das 1-Alpha war für den exponentiellen Zerfall geeignet, was ich für geeigneter halte. Für die sin / cos-Funktionen gilt natürlich sin (t) = sqrt (1-sqr (cos (t)), die Berechnung für sich sollte jedoch schneller sein.
Danny Varod

Wenn das Problem darin besteht, wie die Funktion einer ähnlichen Kurve aussehen könnte, ist Ihre Mathematik korrekt. Das Problem ist jedoch, wie mit dem Mischen von zwei Farben umgegangen wird, z. B. wie 40% Blau + 40% Blau erhalten werden, um 80% Blau zu ergeben.
Epolog

Dies ist einfach zu bewerkstelligen, würde jedoch bei einer Farbsumme von> 100% zu einer schlechten Farbsättigung führen.
Danny Varod
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.