/**/
このチュートリアルでは、4プレーンでchar型のJitterマトリックスが持つアルファチャンネルを透過マスクとして使用し、2つの画像を合成する方法に注目します。jit.lcd オブジェクトによって生成された字幕を動画上にスーパーインポーズする方法を見ていきながら、この概念ついて説明します。
・Jitter Tutorialフォルダにある29jUsingTheAlphaChannel.patというチュートリアルパッチを開いて下さい。
このチュートリアルパッチの左上の領域には、パッチが開かれたときに ozone.mov というファイルを読み込む jit.qt.movie オブジェクトがあります。metro オブジェクトは、trigger オブジェクトを使って、33ミリ秒ごとに jit.qt.movie オブジェクトから新しいマトリックスを出力させ、同時に、この jit.qt.movie の time アトリビュート(QuickTimeの時間単位による動画の現在の再生位置)を出力させています。
動画を再生しながら、新しいマトリックスを出力するごとにその時間位置を取得しています
・metro に接続されている toggle ボックスをクリックして、動画の再生をスタートして下さい。 jit.qt.movie オブジェクトは、マトリックスだけでなく、動画におけるカレントの再生位置の出力も開始します。パッチの下部の jit.pwindow に(字幕付きの!)動画が見えるはずです。
かわいい子猫です
まず、どうやって字幕が生成されるのかを見ていきましょう。その後、それをアルファチャンネルを使って動画に合成する方法を調べてみましょう。
私たちのパッチの字幕は、jit.lcd オブジェクト(パッチの上部にあります)にメッセージを送ることによって生成されます。jit.lcd へのアーギュメントは、オブジェクトによって生成されるマトリックスのプレーン数(planecount)、データ型(type)、ディメンションのサイズ(dim)を指定しています( jit.lcd は、4プレーンで char型のマトリックスだけをサポートします)。jit.lcd オブジェクトは、QuickDrawコマンドの形式でメッセージを受け、bang メッセージを受信したときにそれらを出力マトリックスへ描画します。ここでは、jit.lcd オブジェクトに対して、テキストを描画するためのフォント (font) とテキストスタイル(textface)、そのフォアグラウンド(frgb)とバックグラウンド(brgb)の色(RGB値のリスト)を設定するコマンドを与えて初期化しています。その後、clear メッセージによって jit.lcd オブジェクトが内部に持っているイメージを消去し、bang メッセージによって空のマトリックスを出力します。
初期化された jit.lcd オブジェクト
注:jit.lcd オブジェクトは、QuickDraw のコマンドと関数による完全な命令セットを持っています。この命令セットはMaxの lcd オブジェクトで利用できるものと同じです。このパッチでは、それをテキスト画像の生成のために用いていますが、jit.lcdは、あらゆる種類の2次元のベクトルグラフィックスの生成に用いることが可能です。Max チュートリアルマニュアルのチュートリアル43では、lcdオブジェクトのいくつかの機能を説明していますが、そのほとんどが jit.lcd にも簡単に適用できます。
jit.lcd オブジェクトは、jit.rgb2luma オブジェクトへマトリックスを出力し、jit.rgb2luma オブジェクトは、jit.lcd の4プレーンの画像出力を、1プレーンのグレースケールに変換します。 jit.rgb2luma は、入力マトリックスの各セルの明度の値を持ったマトリックスを生成します。この1プレーンのマトリックスは、その後、alphamask という名前を付けられた send オブジェクトに送信され、同時に jit.pwindow オブジェクトにも送信されて、このマトリックスを実際に見ることができるようになっています。jit.pwindow オブジェクトの border アトリビュートが 1 に設定されていることに注意して下さい。これによって、内側の白い画像の周りに1ピクセルの黒い境界線が表示されます。
jit.lcd オブジェクトは、パッチの他の場所からも(lcdという名前を付けられた receive オブジェクトを経由して)メッセージを受信しています。字幕はムービー再生中に、指定された時間を見つけ出すことによって自動的に生成されます。
jit.qt.movie オブジェクトからの時間解析値
metro オブジェクトと jit.qt.movie オブジェクトの間には t gettime b オブジェクトがあるため、 jit.qt.movie オブジェクトは metro オブジェクトが刻む時間ごとに現在の再生位置を出力します。time アトリビュートは jit.qt.movie オブジェクトの右アウトレットから出力され、 route オブジェクトを使ってメッセージセレクタ(time)が取り除かれます。具体的な時間をよりわかりやすくするためにその値を100で割っています。metro は 33ミリ秒間隔でのみ時間の問い合わせを行なっているため、ある瞬間をスキップしてしまうことは確実にあり得ます。時間の値を100で割ることによって、ムービーの中の必要とするポイントをより見つけやすくしています。
時間の値は、gate オブジェクトを経由しているため、必要ならばそこで字幕を無効にすることもできます。
gate オブジェクトによって時間値の流れを制御しています
・gate に接続されている toggle ボックスをクリックして下さい。字幕が見えなくなるはずです。もう一度 toggle ボックスをクリックすると、字幕の表示が再び始まります。
時間の値 21と40が gate オブジェクトを通ったとき、最終的に字幕が生成されます。selectオブジェクトは、これらの値を受信したときに bang メッセージを出力します。これがメッセージボックスから jit.lcd へコマンドを送信するトリガになります。
時間の値に基づく字幕の動作
jit.lcd へ送られる clear メッセージは、描画領域を消去し、すべてのピクセルを白(バックグラウンドカラーとして選んだ色です)で塗り潰します。moveto メッセージは、jit.lcd オブジェクトのカーソルを次のコマンドで描画を開始する座標へ動かします。write メッセージは、現在選ばれているフォント(font)と字体(textface) を使って、マトリックスにテキストを描画します。字幕の書き込みが終了したら、このオブジェクトに bang メッセージを送信し、新しいマトリックスを出力させます。すべての字幕毎に delay オブジェクトにもbang メッセージを送信しますが、この bang メッセージが1000ミリ秒後にマトリックスをクリアして再び送信させ、タイトルを消去します。
チュートリアルパッチの右側の領域(背景がマゼンタになっています)では、textedit オブジェクトを使って、独自の字幕を生成できるようになっています。Offset と表示されたナンバーボックスで、テキストの水平方向のオフセットを決定します。trigger オブジェクトによって、必要なすべてのQuickDrawコマンドを、正しい順番で jit.lcd オブジェクトに送ることができます。
あなた自身のタイトルを作りましょう
・gate の上にある toggle ボックスで、字幕の自動生成をオフにします。textedit ボックスにいくつかテキスト文字を入力しリターンキーを押して下さい。この文字が画像の上に字幕として表示されます。
画像に重なる新しい字幕
これで、タイトルがどのように生成されるのかがわかりました。今度は、それがどのようにムービー上に合成されるのかを見てみましょう。
ARGB画像のアルファチャンネルは、2つめの画像と合成されたときの透明度を決定します。あるピクセルのアルファチャンネルが0のとき、他の画像の上に合成された場合には完全に透明であるとみなされます。アルファチャンネルが255に設定されているときには完全に不透明だとみなされ、合成された場合、完全に不透明に表示されます。中間の値では、第1と第2の画像の間で滑らかにフェードするようにピクセルを設定します。4プレーンでchar型のJitter マトリックスでは、マトリックスのプレーン0に格納されているデータがアルファチャンネルであるとみなされます。
技術的な詳細:色のシステムとソフトウェア環境によって、アルファチャンネルが画像の「透明度」を表すか、「不透明度」を表すかが異なります。QuickTimeムービーでは(したがってJitteでも)、アルファ値の255は、そのピクセルが完全に「不透明」であるということを意味します。この逆が真であるようなプログラムに出会うかもしれません(すなわち、アルファ値の255が完全な「透明」を意味する場合です)。
jit.alphablend オブジェクトの mode アトリビュートは、アルファチャンネルをそのどちらの方法で扱うことも可能にします。デフォルトの mode 0では、アルファ値の増加を不透明度の増加として扱いますが、mode アトリビュートを1に設定すると、アルファ値の増加を透明度の増加として扱うようになります。
jit.alphablend オブジェクトは、左インレットで受信したマトリックスのアルファチャンネル(プレーン 0)の値を使って、2つのインレットで受信したマトリックス間の(セル毎の)クロスフェードを行います。このパッチでは、jit.qt.movie オブジェクトの出力マトリックスのプレーン0を jit.lcd オブジェクトの出力で置き換えます。その後、この新しいアルファチャンネルを jit.alphablend で使用して、ムービーと、そのムービー自身を反転させたものとの間でのクロスフェードを行います。
jit.pack オブジェクトによる新しいアルファチャンネルの挿入
QuickTimeムービーからのオリジナルのアルファチャンネルを取り出すために、jit.unpack と jit.pack オブジェクトを使います。字幕が入った1プレーンのマトリックスは、jit.pack オブジェクトの上にある receive オブジェクトから jit.pack に送信されます。たとえ receive から新しいマトリックスが送信されていない場合でも、trigger オブジェクトを使って、強制的に jit.pack に新しいマトリックスを出力させている点に注目してください(jit.packはMax の pack オブジェクトに似たもので、最も左のインレットで新しいマトリックスか bang メッセージを受信した場合にのみマトリックスを出力します)。jit.op オブジェクトは、QuickTime ムービーから送信されるオリジナルのマトリックスの「ネガ」を生成します(!- 演算子を使って255からマトリックスの値を減算する方法を使います)。そして、jit.alphablend オブジェクトは、新しいアルファチャンネルを使います。字幕のマトリックスにある白の値ではオリジナルの映像を保ち、黒の値では右側のマトリックスの反転画像を使います。
字幕では、別の方法もよく使われます。画像の上に白いテキスト(黒い縁取りがされている場合もあります)をスーパーインポーズする方法は、反転した映像でアルファマスクを塗りつぶす今回の方法よりはるかに一般的なものです。しかし、ここで使用した字幕の表示方法では、jit.alphablend オブジェクトを使う明確な理由があります。この方法では、バックグラウンドの映像に高いコントラストを持つ領域がある場合に、より読みやすい字幕を提供することができるでしょう。
次の図では、途中の段階を表示する jit.pwindow を使って合成の過程を示しています。
合成処理の流れを示しています
jit.lcd オブジェクトは、Jitterマトリックスへテキストや2次元グラフィックスを描画するためのQuickDrawの完全なコマンドセットを提供します。jit.rgb2luma オブジェクトは、4プレーンのARGBマトリックスを、明度のデータがによる1プレーンのグレースケールマトリックスに変換します。jit.pack オブジェクトを使って、画像のアルファチャンネル(プレーン0)を1プレーンのマトリックスで置き換えることができます。 jit.alphablend オブジェクトは、左側のマトリックスのアルファチャンネルに基づき、2つの画像をセルごとにクロスフェードします。