ドキュメントの内容
この記事で使用しているXHTMLドキュメントは以下のとおりです。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <style> body { background: black; color:#CCCCCC; } #c2 { background-image: url(foo.png); background-repeat: no-repeat; } p { float: left; border :1px solid #444444; padding:10px; margin: 10px; background:#3B3B3B; } </style> <script type="text/javascript;version=1.8" src="main.js"></script> </head> <body onload="processor.doLoad()"> <p> <video id="video" src="video.ogv" controls="true"/> </p> <p> <canvas id="c1" width="160" height="96"/> <canvas id="c2" width="160" height="96"/> </p> </body> </html>
上記のコードの重要な部分は次のとおりです:
1. ID がそれぞれ c1 と c2 の 2 つのキャンバス要素を作成します。 c1 は現在のフレームの元のビデオを表示するために使用され、c2 はクロマキー特殊効果を実行した後にビデオを表示するために使用されます。c2 にはビデオの背景色の部分を置き換えるために使用される静止画像がプリロードされます。
2. JavaScript コードは main.js ファイルからインポートされます。このスクリプトは JavaScript 1.8 の機能を使用するため、スクリプトをインポートするときにバージョンが 22 行目で指定されます。
3. Web ページが読み込まれると、main.js のprocessor.doLoad() メソッドが実行されます。
JavaScript コード
main.js の JS コードには 3 つのメソッドが含まれています。
クロマキーの初期化
doLoad() メソッドは、XHTML ドキュメントが最初にロードされるときに呼び出されます。このメソッドの目的は、クロマキー処理コードに必要な変数を準備し、ユーザーがビデオの再生を開始したときを検出できるようにイベント リスナーを設定することです。
doLoad: function() { this.video = document.getElementById("video"); this.c1 = document.getElementById("c1"); this.ctx1 = this.c1.getContext("2d"); this.c2 = document.getElementById("c2"); this.ctx2 = this.c2.getContext("2d"); let self = this; this.video.addEventListener("play", function() { self.width = self.video.videoWidth / 2; self.height = self.video.videoHeight / 2; self.timerCallback(); }, false); },
このコードは、XHTML ドキュメント内の video 要素と 2 つの Canvas 要素への参照を取得し、さらに 2 つのキャンバスのグラフィックス コンテキストへの参照も取得します。これらは、クロマキー効果を実装するときに使用されます。
addEventListener() はビデオ要素をリッスンし、ユーザーがビデオの再生ボタンを押したときに呼び出されます。ユーザーの再生を処理するために、このコードはビデオの幅と高さを取得して半分にし (クロマキー効果を実行するときにビデオのサイズを半分にします)、次に timerCallback() メソッドを呼び出してビデオ キャプチャを開始します。および視覚効果の計算。
タイマー コールバック
タイマー コールバック関数は、ビデオの再生開始時 (「再生」イベントの発生時) に呼び出され、ビデオの各フレームにキーイング効果を実装するための独自の定期的な呼び出しを担当します。
timerCallback: function() { if (this.video.paused || this.video.ended) { return; } this.computeFrame(); let self = this; setTimeout(function () { self.timerCallback(); }, 0); },
コールバック関数は、まずビデオが再生されているかどうかを確認し、再生されていない場合は何もせず、すぐに戻ります。
次に、computeFrame() メソッドを呼び出します。これにより、現在のビデオ フレームにクロマキー特殊効果が実行されます。
コールバック関数が最後に行うことは、できるだけ早く再呼び出しできるように setTimeout() を呼び出すことです。実際の環境では、ビデオのフレーム レートに基づいて呼び出し頻度を設定することがあります。
ビデオ フレーム データの処理
computeFrame() メソッドは、以下に示すように、実際には各フレームのデータを取得し、クロマキー特殊効果を実行する役割を果たします。
computeFrame: function() { this.ctx1.drawImage(this.video, 0, 0, this.width, this.height); let frame = this.ctx1.getImageData(0, 0, this.width, this.height); let l = frame.data.length / 4; for (let i = 0; i < l; i++) { let r = frame.data[i * 4 + 0]; let g = frame.data[i * 4 + 1]; let b = frame.data[i * 4 + 2]; if (g > 100 && r > 100 && b < 43) frame.data[i * 4 + 3] = 0; } this.ctx2.putImageData(frame, 0, 0); return; }
呼び出されると、video 要素は次のように最新のビデオ フレーム データを表示します:
2 行目で、ビデオ フレームが最初のキャンバスのグラフィックス コンテキスト ctx1 に高さと幅でコピーされます。値は、前に保存したフレームの半分のサイズとして指定されます。 video 要素を描画コンテキストのdrawImage() メソッドに渡すことで、現在のビデオ フレームを描画できることに注意してください。結果は次のようになります:
コードの 3 行目は、最初のキャンバス コンテキストの getImageData() メソッドを呼び出して、現在のビデオ フレームの元の画像データのコピーを取得します。生の 32 ビット ピクセル画像データが提供されるので、それを操作できます。コードの 4 行目では、フレーム画像データの全長を 4 で割ることにより、画像内の総ピクセル数を計算します。
コードの 6 行目は、すべてのピクセルをループし、各ピクセルの赤、緑、青の値を取得し、事前定義された背景色と比較します。これらの背景色は、インポートされた背景画像に置き換えられます。 foo.png。
背景として検出された各ピクセルについて、そのアルファ値をゼロに置き換え、ピクセルが完全に透明であることを示します。その結果、最終イメージの背景部分は 100% 透明になり、13 行目でターゲットのコンテキストに描画されると、コンテンツが静的な背景に重ね合わされるという効果が得られます。
結果の画像は次のようになります:
ビデオの再生中にこれを繰り返し実行すると、フレームごとに処理され、クロマキー効果が表示されます。
HTML5 の詳細については、Canvas を使用してビデオをリアルタイムで処理する、PHP 中国語 Web サイトに注目してください。