コントロールの値をロジックで使う
このページは映像エフェクトプラグイン作成入門 の一部です。
/icons/-.icon
前回と前々回でエフェクトにロジックとコントロールを追加しました。
今回はコントロールの値を取得してロジックに反映させます。
例えばスライダーの数値にあわせて描画位置が動くエフェクトをつくれる。
SimpleEffectProcessorクラスを編集していきます。
アニメーションスライダーの値を取得する
まずはUpdateメソッド内でスライダーの値を取得しましょう。
スライダーの値は以下のように取得できます。
code:cs
var frame = effectDescription.ItemPosition.Frame;
var length = effectDescription.ItemDuration.Frame;
var fps = effectDescription.FPS;
var x = item.X.GetValue(frame, length, fps);
frameはアイテムの先頭から数えた現在のフレーム、lengthはアイテムの長さを表しています。
frame, length, fpsからアニメーションスライダーの数値を取得してxに代入しています。
描画位置に反映させる
code:cs
public DrawDescription Update(EffectDescription effectDescription)
{
var frame = effectDescription.ItemPosition.Frame;
var length = effectDescription.ItemDuration.Frame;
var fps = effectDescription.FPS;
var x = item.X.GetValue(frame, length, fps);
return effectDescription.DrawDescription with
{
Draw = new(
effectDescription.DrawDescription.Draw.X + (float)x,
effectDescription.DrawDescription.Draw.Y,
effectDescription.DrawDescription.Draw.Z)
};
}
このコードで(float)という表記を見つけた方がいるかもしれません。
実は描画位置のXYZはfloatという型である必要があります。
しかし、item.X.GetValue(frame, length, fps)で取得できる値はdoubleという型です。
そのため(float)xと書いてfloat型に変換する必要があります。
ビルドしてみましょう。スライダーを動かすとアイテムのX座標が変わることが確認できると思います。
トグルの値を取得する
アニメーションスライダーは値の取得が面倒でしたが他のコントロールは簡単に取得できます。
次のようにしてトグルの値を取得できます。
code:cs
var invert = item.Invert;
描画位置の反転処理を追加する
Updateメソッドを以下のように書き換えてください。
code:cs
public DrawDescription Update(EffectDescription effectDescription)
{
var frame = effectDescription.ItemPosition.Frame;
var length = effectDescription.ItemDuration.Frame;
var fps = effectDescription.FPS;
var x = item.X.GetValue(frame, length, fps);
var invert = item.Invert;
if (invert)
{
x *= -1;
}
return effectDescription.DrawDescription with
{
Draw = new(
effectDescription.DrawDescription.Draw.X + (float)x,
effectDescription.DrawDescription.Draw.Y,
effectDescription.DrawDescription.Draw.Z)
};
}
Invertを取得して、Invertがtrueだった場合にx *= -1;を実行します。
x *= -1はx = x * -1を省略したものです。
ビルドしてエフェクトを使用してみましょう。
反転をオンにするとスライダーの数値のプラスマイナスが反転するはずです。
練習問題
新しくY座標のアニメーションスライダーを追加してY座標を変更できるようにしてください。
また、反転にも対応させてください。
実装例
この他にもいろいろなやり方が考えられます。
code:SimpleEffect.cs
using System.ComponentModel.DataAnnotations;
using YukkuriMovieMaker.Commons;
using YukkuriMovieMaker.Controls;
using YukkuriMovieMaker.Exo;
using YukkuriMovieMaker.Player.Video;
using YukkuriMovieMaker.Plugin.Effects;
namespace VideoEffectPluginTutorial
{
class SimpleEffect : VideoEffectBase
{
public override string Label => "シンプルエフェクト";
public Animation X { get; } = new Animation(0, -9999, 9999);
public Animation Y { get; } = new Animation(0, -9999, 9999);
public bool Invert { get => invert; set => Set(ref invert, value); }
bool invert = false;
public override IEnumerable<string> CreateExoVideoFilters(int keyFrameIndex, ExoOutputDescription exoOutputDescription)
{
return [];
}
public override IVideoEffectProcessor CreateVideoEffect(IGraphicsDevicesAndContext devices)
{
return new SimpleEffectProcessor(devices, this);
}
protected override IEnumerable<IAnimatable> GetAnimatables() => X, Y; }
}
code:SimpleEffectProcessor.cs
using Vortice.Direct2D1;
using YukkuriMovieMaker.Commons;
using YukkuriMovieMaker.Player.Video;
namespace VideoEffectPluginTutorial
{
class SimpleEffectProcessor : IVideoEffectProcessor
{
readonly SimpleEffect item;
ID2D1Image? input;
public SimpleEffectProcessor(IGraphicsDevicesAndContext devices, SimpleEffect item)
{
this.item = item;
}
public ID2D1Image Output => input ?? throw new NullReferenceException(nameof(input) + " is null");
public void ClearInput()
{
input = null;
}
public void Dispose()
{
}
public void SetInput(ID2D1Image? input)
{
this.input = input;
}
public DrawDescription Update(EffectDescription effectDescription)
{
var frame = effectDescription.ItemPosition.Frame;
var length = effectDescription.ItemDuration.Frame;
var fps = effectDescription.FPS;
var x = item.X.GetValue(frame, length, fps);
var y = item.Y.GetValue(frame, length, fps);
var invert = item.Invert;
if (invert)
{
x *= -1;
y *= -1;
}
return effectDescription.DrawDescription with
{
Draw = new(
effectDescription.DrawDescription.Draw.X + (float)x,
effectDescription.DrawDescription.Draw.Y + (float)y,
effectDescription.DrawDescription.Draw.Z)
};
}
}
}
/icons/-.icon