web-dev-qa-db-ja.com

完璧なクロスフェード

この問題を言葉で説明するのは難しいと思うので、それを説明するためにビデオ(45秒)を作成しました。これが質問のプレビューです。Vimeoで確認してください: http://vimeo.com/epologee/perfect-crossfade

Using a linear crossfade the resulting image will have a 'dip' in transparency. How can I prevent this?

2枚の画像または形状の完璧なクロスフェードまたはディゾルブを作成するという問題は、過去10年間、多くの分野で繰り返し発生しています。最初はビデオ編集、次にFlashアニメーション、そして今はiOSプログラミングです。あなたがそれをグーグルで始めるとき、見つけられるべき多くの回避策があります、しかし私は今度はハックなしでこれを本当に解決したいと思います。

要約:
2つの半透明の同じ色のビットマップをクロスフェードするときに適用される手法または曲線の名前は何ですか?結果の透明度をいずれかのオリジナルと一致させたい場合はどうしますか?

フェード中に必要な部分透明度/アルファ値を計算する(数学)関数はありますか?

ActionScriptまたはCocoaにあるease inease out、またはease in out関数のように、これらの関数をプリセットとして持つプログラミング言語はありますか?

更新:ビデオに加えて、サンプルプロジェクト(XcodeおよびiOS SDKが必要)を作成し、それをgithubに投稿しました。ビデオと同じアニメーションが表示されますが、今回は正方形で表示されます https://github.com/epologee/StackOverflow-Example-Code

25
epologee

それは不可能だと思います。これは、2つのオブジェクトがオーバーレイする場合の透明度の計算方法です。 http://en.wikipedia.org/wiki/Alpha_compositing

Alpha compositing

オーバーレイ領域が透けて見えないようにするには、オブジェクトの1つに不透明度1が必要です。

3
b123400

ビデオ編集の分野でどのような名前になるかわかりませんが、曲線をS曲線または S字曲線 と呼びます。 Core Animationの kCAMediaTimingFunctionEaseInEaseOut タイミング関数を使用して、iOSで探しているクロスフェードを生成するのは非常に簡単です。そのタイミング関数を使用して、2つのビューのalphaプロパティを反対方向(1つは0-> 1、もう1つは1-> 0)にアニメーション化するだけです。

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

注:UIViewの便利なメソッドではなく、ブロックベースのアニメーションメソッドを実際に使用する必要があります。上記のUIViewのメソッドを使用したのは、理解が非常に簡単で、メモリから入力するのが簡単だからです。ただし、ブロックの使用はそれほど難しくありません。

補遺:UIViewAnimationEaseInOutが気に入らない場合は、 タイミング、タイムスペース、およびCAAnimation で説明されているように、独自のタイミング関数を作成できます。 =。これは、上に示した単純なアニメーションよりも少し高度ですが、必要なすべてのコントロールを提供します。

3
Caleb

コンピュータグラフィックスでは、この種の関数は smoothstep と呼ばれます。クロスフェードに使用すると、コンポジションのグローバルアルファ値が決まります。

入力画像にアルファチャネルがある場合は、最初にアルファが premultiplied であることを確認する必要があります。次に、各チャンネルでsmoothstep alphaを使用してクロスフェード合成を簡単に行うことができ[X = A*alpha + B*(1-alpha)]、妥当な結果を期待できます。

1
comingstorm

指数関数的減衰関数を使用できます。

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

グラフは次のようになります。

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