ElectronでdesktopCapturerをする際に、file,blob,dataUriを扱ったので、忘れないうちにメモしておきます。
desktopCapturer.getSources(options, callback)
をすると、callbackに DesktopCapturerSource objects
なるものが帰ってきて、
そのプロパティにNativeImage
があって、NativeImageのインスタンスのメソッドの中にtoPNG
というものがあり、直接ローカルに保存するのはnode.jsのfs.writeFile
で実現できたのですが、Rails5のAPIを叩いてファイルをPOSTする方法がわからずにいました。
HTMLのフォームを作成してsubmitするのはできたのですが、フォームを使わずにPOSTしたかったのです。
結論は、FormDataにfileオブジェクトをappendして、POSTすればよかったのでした。
これをするために、toDataURLメソッドからfileオブジェクトを生成しました。以下、その内容です。
##DataURLをざっくり知る
dataURIや、dataURIスキーム、dataスキームのURL、などと言われるみたいです。dataスキームが先頭についているURLということでしょう。
DataURLは、<img src='ココと置換可能'>
です。
DataURLのサンプルはこんな感じです。data:image/png;base64,iVBO...(長いので以下略)
srcにhttpから始まるURLを指定すると、データの読み込みにhttp通信が発生して時間がかかりますが、dataURIだと通信がいらないため、処理が早く済むのだとか。
詳しく知りたい場合はData URI Scheme についてをご覧ください。
補足:スキームとは
{スキーム名}:{スキームの中身?}
で表され、スキーム名には「file, blob, data, http, ftp」などがあります。
Blobをざっくり知る
クラスです。バッファデータとコンテンツタイプデータを引数にもちます。
new Blob ( [バッファデータ], オプション )
するとBlobオブジェクトが返ってきます。ローカルにあるファイルと同じ雰囲気。
Fileをざっくり知る
同じく、クラスです。BlobクラスはFileクラスから派生しています。Blob > File。
new File ( [バッファデータ], ファイル名, オプション )
するとFileオブジェクトが返ってきます。
desktopCapturerで取得する画像ファイルは、名前をつけてAPIにPOSTして、carrierwave経由でフォルダに保存したかったので、Fileクラスでファイル名を指定できるのは助かりました。
BlobとFileを詳しく知りたい場合はBlob と File クラスについてをご覧ください。
Bufferをざっくり知る
node.jsではBufferクラス、JavaScriptではMDNにArrayBufferのドキュメントがあります。
MDNではこのように説明されています。
ArrayBuffer は、一般的な固定長のバイナリデータのバッファを示すために使われるデータタイプです。
###補足:バッファとは
引用した説明文が理解不能だったので単語を調べてみると、バッファとは、データを一時的に保持するための場所のようです。
###補足:バイナリデータとは
バイナリ形式のデータのことで、コンピュータが理解できるデータのようです。この文章みたいに、人間が読んでわかるデータは、テキストデータと言われるそうです。
###補足:データタイプとは
データ型のようです。文字列型とか整数型とかブーリアン型とか。その仲間には、バイナリ型というバイナリデータを扱うデータタイプもあるようです。
Data URIをBlob/Fileにする
function dataURIConverter(dataURI) {
// base64/URLEncodedデータを文字列としてバイナリデータに変換する
var byteString = atob(dataURI.split(',')[1]);
// mimetypeを抜き出す
var mimeType = dataURI.split(',')[0].split(':')[1].split(';')[0];
// バイナリデータを扱えるように、typed arrayに書き換えていく
var buffer = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
buffer[i] = byteString.charCodeAt(i);// charCodeAtで配列に
}
// 第一引数は配列で渡し、Fileオブジェクトを返す。
return new File([buffer], 'ファイル名', { type:mimeType } );
}
desktopCapturer.getSources(options, function(error, sources) {
sources.forEach(function(source) {
var val = dataURItoFile(source.thumbnail.toDataURL());
var formData = new FormData();
formData.append('key', val);
// ajaxなどでformDataをPOSTしてAPIを叩く。(詳細は割愛)
}
}
その他参考にさせていただいたページ
base64について
Data URIからBlob(File)を作成する方法
Convert Data URI to File then append to FormData
詳しく知るには、まだまだ調べることがたくさんありそうです。