写真を外部ストレージにアップロードする場合などに、Blob形式の写真データが必要になることがあるかと思います。しかしCameraプラグインの写真の取得形式はURIまたはbase64になるため、そのままではBlobデータとして扱えません。
JavaScriptでBlobデータを作るにはnew Blob()
を使いますが、このコンストラクタ引数にはArrayBuffer(など)の形式のデータを指定しなければなりません。そのため、写真のURIから最終的にBlobへ変換するには、少々面倒ですが以下の手順を経由する必要があります。
- Cameraプラグインで写真のURIを取得
- URIからFileEntryに変換
- FileEntryからFileオブジェクトを取得し、ArrayBufferに変換
- ArrayBufferからBlobに変換
変換処理には、HTML5のFile APIを利用します。
それでは各手順を詳しく解説していきます。
1. Cameraプラグインで写真のURIを取得
まずは写真をURI形式で取得します。
// 写真を読み込み
navigator.camera.getPicture(onSuccess, onError, {
sourceType : Camera.PictureSourceType.PHOTOLIBRARY,
destinationType: Camera.DestinationType.FILE_URI
});
// 写真のURIが取得される
function onSuccess(imageURI) {
// URIからFileEntryに変換
URItoFileEntry(imageURI);
}
// エラー時の処理
function onError(error) {
console.log(error);
}
2. URIからFileEntryに変換
FileEntry
は、ローカルのファイルシステム内のファイルを表すインターフェースです。
window.resolveLocalFileSystemURL()
によって、FileEntry
を取得することができます。
この処理は非同期的に実行され、処理が完了すると第二引数に指定したコールバック関数にFileEntry
が渡されます。
// URIからFileEntryに変換する
function URItoFileEntry(imageURI) {
window.resolveLocalFileSystemURL(imageURI, fileEntryToArrayBuffer, onError);
}
3. FileEntryからFileオブジェクトを取得し、ArrayBufferに変換
FileEntry.file()
によって、読み込み可能なファイルを表すFile
オブジェクトを取得します。
そしてファイルの読み込み機能を提供するFileReader
オブジェクトを生成し、FileReader.readAsArrayBuffer()
によって、File
オブジェクトをArrayBuffer
形式に変換します。このメソッドは非同期で実行され、読み込みが完了するとFileReader.onloadend
イベントが発火します。
// FileEntryからFileオブジェクトを取得し、さらにArrayBufferに変換する
function fileEntryToArrayBuffer(fileEntry) {
// Fileオブジェクトを取得
fileEntry.file((file) => {
// FileReaderを生成
let reader = new FileReader();
// ArrayBuffer形式への変換完了時の処理
reader.onloadend = ArrayBufferToBlob;
// ArrayBuffer形式に変換
reader.readAsArrayBuffer(file);
}, onError);
}
// エラー時の処理
function onError(error) {
console.log(error);
}
4. ArrayBufferからBlobに変換
FileReader.onloadend
イベントのイベント引数に、ArrayBuffer
オブジェクトが格納されています。あとはこのArrayBuffer
オブジェクトを配列形式にしてnew Blob()
のコンストラクタに指定するだけです。
// ArrayBufferからBlobに変換する
function ArrayBufferToBlob(event) {
let blob = new Blob([event.target.result])
}
ソースコード全文
// 写真を読み込み
navigator.camera.getPicture(onSuccess, onError, {
sourceType : Camera.PictureSourceType.PHOTOLIBRARY,
destinationType: Camera.DestinationType.FILE_URI
});
// 写真のURIが取得される
function onSuccess(imageURI) {
// URIからFileEntryに変換
URItoFileEntry(imageURI)
}
// URIからFileEntryに変換する
function URItoFileEntry(imageURI) {
window.resolveLocalFileSystemURL(imageURI, fileEntryToArrayBuffer, onError);
}
// FileEntryからFileオブジェクトを取得し、さらにArrayBufferに変換する
function fileEntryToArrayBuffer(fileEntry) {
// Fileオブジェクトを取得
fileEntry.file((file) => {
// FileReaderを生成
let reader = new FileReader();
// ArrayBuffer形式への変換完了時の処理
reader.onloadend = ArrayBufferToBlob;
// ArrayBuffer形式に変換
reader.readAsArrayBuffer(file);
}, onError);
}
// ArrayBufferからBlobに変換する
function ArrayBufferToBlob(event) {
let blob = new Blob([event.target.result])
}
// エラー時の処理
function onError(error) {
console.log(error);
}
このようにFile APIを使うと、バイナリデータを様々な形式に変換することができます。
CameraプラグインはFile APIとの併用によって、できることが増えると覚えておくと良いでしょう。