チュートリアル29

アルファチャンネルの使用


このチュートリアルでは、透過マスクとして4プレーンcharのJitterマトリクスのアルファチャンネルを使い、2つの画像を合成する方法を見ていきます。jit.lcdオブジェクトによって生成された字幕を動画上にスーパーインポーズする方法で、このコンセプトを検討してみましょう。

・Jitter Tutorialフォルダにある29jUsingTheAlphaChannel.patというチュートリアルパッチを開いてください。

このチュートリアルパッチの左上の領域には、パッチが開かれたときにozone.movというファイルを読み込むjit.qt.movieオブジェクトがあります。metroオブジェクトは、33ミリ秒毎にjit.qt.movieオブジェクトから新しいマトリクスを出力し、triggerオブジェクトを使ってそのオブジェクトのtimeアトリビュート(QuickTimeの時間単位による動画の現在の再生位置)を取得します。


動画の再生、それぞれ新しいマトリクスを伴う現在の時間位置の取得

metroに付いているtoggleボックスをクリックして、動画の再生をスタートしてください。 jit.qt.movieオブジェクトは、動画内の現在の再生位置と一緒にマトリクスを出力をし始めるでしょう。あなたには、パッチの下の方のjit.qwindowに(字幕付きの!)動画が見えるはずです。


可愛い子猫ちゃん


まず、どうやって字幕が生成されるのかを見ていきましょう。それから、それをアルファチャンネルを使って動画に合成する方法を調べていきましょう。


jit.lcdオブジェクト

私達のパッチの字幕は、jit.lcdオブジェクト(パッチの上部にあります)にメッセージを送ることで生成されます。jit.lcdへのアーギュメントは、そのオブジェクトによって生成されるマトリクスのplanecount,、type、dimを指定します(jit.lcdは、4プレーンでcharのマトリクスだけをサポートします)。jit.lcdオブジェクトは、QuickDrawコマンドの形式でメッセージを受け、bangメッセージを受け取ったときに出力マトリクスへそれらを描画します。描画するテキストとそのフォアグラウンド(frgb)とバックグラウンド(brgb)の(RGB値の並びの)色として、jit.lcdにfontとtextfaceを設定するためのコマンドを与えて、jit.lcdを初期化します。それからjit.lcdオブジェクトの内部画像を消去し、bangメッセージと一緒に空のマトリクスを出力します。


初期化されたjit.lcdオブジェクト

注意:jit.lcdオブジェクトには、Maxのlcdオブジェクトで動作し、QuickDrawのコマンドと機能に等しい完全な命令セットがあります。このパッチでは、それをテキスト画像の生成のために使いますが、jit.lcdは、あらゆる種類の2次元のベクトルグラフィックスの生成のために使うことができます。Max Tutorials and Topicsマニュアルのチュートリアル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オブジェクトからの時間値の解析


jit.qt.movieオブジェクトは、metroオブジェクトとの間にt gettime bオブジェクトがあるので、 metroオブジェクトが刻む時間毎に現在の再生位置を出力します。timeアトリビュートは、jit.qt.movie オブジェクトの右アウトレットから出力され、routeオブジェクトを使って、そのメッセージセレクタ(time)(訳注:routeオブジェクトのアーギュメント)で抜き出すことができます。より確実に特定の時間を求めるために、その値を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メッセージを送っています。それはタイトルを消去するために、1000ミリ秒後にマトリクスをクリアして送り直すものです。


あなた自身のタイトルを作りましょう

チュートリアルパッチの(マゼンダの背景になっている)右側の領域で、あなた自身の字幕を生成するための texteditオブジェクトが使えるようなっています。Offsetというラベルが付いたナンバーボックスで、textに対する横軸のオフセットを決めます。triggerオブジェクトは、必要なすべてのQuickDrawコマンドを、正しい順番でjit.lcdオブジェクトに送れるようにします。


あなた自身のタイトルを作りましょう


gateの上にあるtoggleボックスで、字幕の自動生成をオフにします。texteditボックスにいくつか文字を入力しリターンキーを押してください。画像にスーパーインポーズされたそのテキストが見えるでしょう。


画像に重なる新しい字幕


これで、タイトルがどう生成されるのかがわかりました。今度は、それが動画上にどう合成されるのかを見てみましょう。


アルファチャンネル

ARGB画像のアルファチャンネルは、2つめの画像と合成されたときの透明度を決定します。もし、あるピクセルのアルファチャンネルが0なら、他の画像の上に合成されたときに、それは完全に透明だとみなされます。もし、ピクセルのアルファチャンネルが255に設定されれば、それは完全に不透明だとみなされ、合成されたときには完全な不透明さで表示されます。中間の値では、1つめと2つめの画像の間を滑らかに重ねたピクセルにします。4プレーンでcharのJitterマトリクスでは、マトリクスのプレーン0に格納されているデータがアルファチャンネルだと判断されます。

技術的詳細:色のシステムとソフトウェア環境によっては、アルファチャンネルが画像の透明度表すのか、不透明度を表すかが異なります。QuickTimeムービーでは(それゆえJitteでも)、アルファ値の255は、そのピクセルが完全に不透明だということを意味します。その反対になっているプログラムに出会うかもしれません(すなわち、アルファ値の255は完全な透明さを意味します)。jit.alphablendオブジェクトのmodeアトリビュートは、アルファチャンネルをそのどちらの方法でも扱えるようにします。デフォルトモードの0では、アルファ値の増加を不透明度の増加として扱いますが、modeアトリビュートが1の設定では、アルファ値の増加を透明度の増加として扱うようにします。


jit.alphablendオブジェクトは、その2つのインレットに届いたマトリクス間の(セル毎の)クロスフェードを行うために、左インレットに届いたマトリクスのアルファチャンネル(プレーン0)に格納されている値を使います。私達のパッチは、jit.qt.movieオブジェクトの出力マトリクスのプレーン0をjit.lcdオブジェクトの出力に置き換えます。そして、動画と、その動画の反転したものとのクロスフェードを行う jit.alphablendで、この新しいアルファチャンネルを使います。


jit.packオブジェクトでの新しいアルファチャンネルの挿入


QuickTimeムービーからの元のアルファチャンネルを取り出すために、jit.unpackjit.packオブジェクトを使います。字幕が入った1プレーンのマトリクスは、jit.packオブジェクトの上のreceiveオブジェクトからjit.packオブジェクトに届きます。receiveから新しいマトリクスが届いていないときも、強制的に jit.packが新しいマトリクスを出力するために、triggerオブジェクトがどう使われているかに注意してください(Maxのpackオブジェクトに似たjit.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つの画像をセル毎にクロスフェードします。