AviSynthのぺーじ/関数の作成方法
これは、かつて「にーやんのAviSynthのぺーじ」として公開されていたものを転載したものです。内容は古く、間違いも含まれている可能性があります。より正確で新しい情報を知りたい場合は、AviSynth 付属のヘルプや AviSynth 公式サイトを参考にすることをおすすめします。AviSynth Wiki の AviSynth入門なども活用してください。
関数化の方針 †
前回のおさらいです。
前回、私は、Cropフィルタに対する不満として、次の3つを挙げました。
- 書式1で、width・heightの指定方法はわかりづらい。
- 書式2で、負の符号を付けなければならないのが、ややこしい。
- どちらの書式においても、引数の順序が直感的ではない。 では実際に、関数を作っていくことにしましょう。
いろいろなやり方があるとは思いますが、ここでは、上の3つの不満を元に、関数の概要(どのような関数にするか)を考えることから始めてみます。
[関数の概要] †
- 関数名
- EasyClipping
- 関数化の方針
- すべてのバージョンのAviSynthで使えるように、書式1をベースとする。
- 書式2のように、クロップ幅はleft・top・right・bottomで指定する。
- 引数の順番を入れ替えて、上下左右(top, bottom, left, right)の順に指定できるようにする。
- 1,2から、widthとheightは、引数とクリップ属性フィルタを利用して求める。 おおざっぱにですが、このように考えてみました。
問題は、引数の順番を入れ替えることと、いかにして書式1の引数widthとheightを求めるかということの2点です(書式2をベースにすれば、後者は関係ありません)。4.のクリップ属性フィルタについては、後述します。
EasyClipping関数の作成 †
(1)関数名と引数リスト †
さて、まずは作りやすいところから、順に作っていくことにしましょう。作っていくうちに、もしマズイ部分が出てきたら、その都度、直せばいいのですから。
この場合、関数名と引数がすでに決まっていますので、ここから作り始めることにします。関数の1行目、「function 関数名(引数リスト)」の部分です。
関数名はEasyClipping、引数はclipとtop, bottom, left, rightの5つですから、関数の1行目は次のようになります。
function EasyClipping(clip clip, int top, int bottom, int left, int right ) { ... }
まず最初に、clip型の引数(例ではclip)が必要となります。
ビデオ -----> 関数(clip, [...])
このようにclip型の引数があることによって、ビデオを受け入れて、そのビデオに対して関数を実行することができるのです。いわば、ビデオの入り口を作ってやるわけです。
他の引数については、関数化の方針3の通り、top, bottom, left, right(上下左右)の順にしました。
この4つの引数のデータ型は、Cropフィルタの各引数と同じint型にします。
必ず、「データ型1 引数1, データ型2 引数2, データ型3 引数3, ...」という風に記述してください。
(2)メイン関数 †
では次に、メインとなる関数内部を作っていきます。{ }で囲まれた範囲のことです。
関数の内部は、たとえば下記のように記述します(一例)。
{ clip = フィルタ(clip [, 引数] ) return clip }
これは、変数を使った記述法と一緒ですね。
あるいは、変数とreturn文を省略して、次のように書くことも出来ます。
{ フィルタ(clip [, 引数] ) }
関数といっても、まったく新しいフィルタを作るわけではありません。
関数の内部では、既存のフィルタ(または別の関数)を実行し、その結果を返します。
EasyClipping関数 ↓ 引数(clip, top, bottom, left, right) ↓ Crop(clip, left, top, ...)
ですから、関数の中においても、通常のスクリプトと同様に記述すればいいわけです。
具体的には、次のように記述します。
function EasyClipping(clip clip, int top, int bottom, int left, int right ) { clip = Crop(clip, left, top, width, height) return clip }
Cropフィルタを、そのまま記述しただけです(変数を省略した記述法でも構いません)。
EasyClipping関数で指定されたclip, top, leftの値が、そのまま、Cropフィルタのclip, top, leftに、それぞれ代入されます。引数の順番を入れ替えること自体は、この方法で実現できます。
ただし、このままでは動作しません。Cropフィルタのwidthとheightが指定されていないからです。
では、どうすれば、widthとheightを求めることができるのでしょうか?
ここで登場するのが、クリップ属性フィルタです。
クリップ属性フィルタ:Width() / Height() †
クリップ属性(Clip Properties)フィルタは、ビデオクリップのサイズ、色空間、フレームレートといったクリップに関する情報を取得することができるフィルタです。
ここでは、クリップの高さを調べるHeight()と、幅を調べるWidth()を使います。
Height(clip) Width(clip)
どちらも引数はクリップのみです。ですから、
Width(clip) #またはclip.Width()
これで、ビデオクリップ(clip)の高さを求めることができます。また、Widthの部分をHeightに置き換えれば、幅を求めることができます。
さて、ここで私たちが求めなければならないのは、Cropフィルタの書式1の引数widthとheightでした。これは、Cropした後の、画像の幅と高さでしたね。
今や私たちは、クリップ属性フィルタを使って、元の画像全体の幅と高さを知ることができるようになりました。
これらの値とEasyClipping関数の引数(top, bottom, left, right)を組み合わせれば、widthとheightを求めることもできます。
つまり上の図で言うと、クリップ全体の幅(clip.Width())から、leftとrightを引けば、widthを求めることができるのです。
これをスクリプトで表すと、次のようになります。
width = Width(clip) - (left + right)
同様にして、heightも、次のように求めることができます。
height = Height(clip) - (top + bottom)
これを、EasyClipping関数に組み込んでみます。
function EasyClipping(clip clip, int top, int bottom, int left, int right ) { #//--- widthとheightを求める ---// width = Width(clip) - (left + right) height = Height(clip) - (top + bottom) #//--- Cropフィルタ(書式1) ---// clip = Crop(clip, left, top, width, height) #//--- return文 ---// return clip }
これで、EasyClipping関数は、"一応"、動作するようになったと思います。
"とりあえず"、EasyClipping関数の完成です。
最終更新日 2004年7月11日