HowToApplyFilterToManySingleFrames
特定のフレームや範囲にだけフィルタをかけたい場合、AviSynthではApplyRangeフィルタやFilterRange関数を使って、これを行うことができます(参照)。
しかし、その対象フレームや対象範囲が複数に渡るときは、これらのフィルタを何度も呼び出す必要が出てきます。それは、スクリプトを書く手間がかかるだけでなく、AviSynthに負荷をかけてしまうことにもなりかねません。
AviSynth.orgに掲載されているHowToApplyFilterToManySingleFramesを使えば、なるべくAviSynthに負担をかけずに、かつ、比較的簡単に、複数の範囲にフィルタをかけることができます。この方法では、AviSynthに内蔵されているConditionalFilterフィルタとConditionalReaderフィルタを使用します。
ソースクリップ
例として、このビデオクリップの1フレームと3-4フレームだけに、GreyScaleフィルタを適用したいと思います。GreyScaleフィルタは、ビデオクリップをグレースケールに変換するフィルタです。
global FreezeThis = 0
video = ColorBars(80,60) # ソースクリップ
frozen = video.GreyScale() # 適用したいフィルタ
ConditionalFilter(video, frozen, video, "FreezeThis", "==", "1")
ConditionalReader("Setting.txt", "FreezeThis", false)
ここでは細かい説明は省きますが、「"FreezeThis"
」の値が1ならフィルタ適用後のクリップ(frozen)を選択、そうでなければオリジナルのクリップ(video)を選択するという内容になっています(いずれAviSynth Wikiで、もう少し詳しく説明するかもしれません)。
2行目のクリップのパスと3行目の適用したいフィルタ、そして5行目のSetting.txtさえ変更すれば、ほかのフィルタを使用したい場合にも応用できます。
これとは別にSetting.txt(上記スクリプトの5行目で指定)を用意します。これは、"FreezeThis"
の値を設定するためのファイルです。
Setting.txtは、次のように記述します。
type int
default 0
1 1
R 3 4 1
1行目:
type int
データがint型(整数)であることを宣言しています。この場合、とくに変更する必要はありません。
2行目:
default 0
デフォルト値を設定しています。指定されなかったフレームには、この値が適用されます。
今回の例では「"FreezeThis"
」の値が1ならfrozenを選択することになっているので、デフォルトは0にしておきます。これも変更する必要はありません。
3行目:
3行目以降で、フィルタを適用したいフレーム(または範囲)を指定します。
1 1
左がフレーム番号、右が値です。このように値を1に設定すると、そのフレーム(この場合は1フレーム)ではfrozenが選択されます。
4行目:
R 開始フレーム 終了フレーム 値
範囲を指定したいときは、このように記述します。RはRange(範囲)のRです。
R 3 4 1
例の場合、3から4フレームまでの値を1に設定していることになり、その範囲はfrozenが選ばれることになります。
さらにフレームを指定したい場合は、同様にして設定を追加していきます。
フィルタ適用後
上記のスクリプトを実行すると、このようになりました。Setting.txtで指定したフレームだけが、グレースケールになっています。