必要な効率の軸 (帯域幅と CPU 効率) に応じて、いくつかの方法をお勧めします。
オプション 1:キャンバスの toDataURL メソッドを使用できます。これは、キャンバス イメージ データの base64 でエンコードされたイメージを返します。指定した画像形式 (またはデフォルトでは PNG) を使用して圧縮され、WebSocket 経由で送信するために base64 に事前にエンコードされます。
canvas = document.getElementById("mycanvas");
b64png = canvas.toDataURL();
ws.send(b64png);
オプション 2:非可逆圧縮を許容できる場合は、 toDataURL メソッドから base64 でエンコードされた JPEG として画像を要求できます。
canvas = document.getElementById("mycanvas");
b64jpeg = canvas.toDataURL("image/jpeg");
ws.send(b64jpeg);
オプション 3:バイナリ WebSocket データ (Chrome、Firefox、IE 10) をサポートするブラウザーを使用している場合は、キャンバス配列バッファーを WebSocket 経由で直接送信できます。
canvas = document.getElementById("mycanvas");
ctx = canvas.getContext('2d');
imgdata = ctx.getImageData(0,0, width, height).data; // This is a Uint8ClampedArray
ws.send(imgdata.buffer); // Send the ArrayBuffer from the Uint8ClampedArray
オプション 3 は、帯域幅の点では最も効率的ではありませんが、クライアント側とサーバー側の処理能力の点では最も効率的です。これは、画像データが生で送信され、前処理と後処理がほとんど必要ないためです。
帯域幅効率が最も高いオプションはおそらく #2 ですが、画像データを JPEG 形式に変換する際に画質がいくらか低下します。さらに、base64 でデータを arraybuffer または blob にデコードし、それをバイナリ WebSocket 経由で送信して、base64 帯域幅の 33% のオーバーヘッドが発生しないようにすることもできますが、これにより CPU オーバーヘッドがさらに増加します。
画質を損なうことなく効率的な帯域幅が必要な場合は、オプション #2 が最適です。
いくつかのメモ/警告:
toDataURL は、base64 データの前に次のようなプレフィックスを付けます。
"data:image/png;base64,iVBORw0KGgoAAAA..."
データ URL 形式の優れた点の 1 つは、全体を取得してブラウザーのアドレス バーに貼り付けると、ブラウザーが画像をレンダリングすることです。
toDataURL の詳細については、MDN Canvas ページを参照してください。