画像ファイルの保存と表示
続いて、画像ファイルの保存と表示を行います。画像ファイルの保存と言っても基本的にはテキストの場合と同様でリスト8のようになります。今回保存する画像パスは先ほど紹介したcdvfileプロトコルを使って指定しています。
var file_element = $('#file')[0];
var file = file_element.files[0];
if(file) {
$scope.filename = file.name;
//(1)ファイルを参照するためのFileReaderを作成
var reader = new FileReader();
//(2)ファイルの読み込みが終了したタイミングでファイルに保存する
reader.onloadend = function(evt){
window.resolveLocalFileSystemURL(
"cdvfile://localhost/cache/", //(3)cdvfileプロトコルの利用
function(dir) {
dir.getFile($scope.filename, {create: true}, function(entry) {
entry.createWriter(function(writer) {
//(4)ファイルの書き込み
writer.write(reader.result);
});
});
}
);
};
//(5)ファイルをArrayBufferとして読みこむ
reader.readAsArrayBuffer(file);
}
画像ファイルを読みこむ処理は、CordovaのプラグインAPIではなく、ブラウザのAPIを使っていますのでWebアプリなどで処理を記述する場合と同じです。
最初に、(1)FileReader作成し、ファイルの読込が終了したタイミングであるonloadendハンドラ(2)で、これまでと同様にファイルを保存します。
今回はcdvfileプロトコルを使っていますので、(3)のようにcdvfileプロトコルでのURL形式で指定しています。実際のファイルの書き込み処理(4)は今までと全く同様です。
(5)ファイルの読み込みではArrayBufferとしてファイルを読みこむ必要があります。この部分がテキストと異なります。reader.resultもテキストの場合とはことなり、ArrayBuffer形式ですが、それらの違いにかかわらず、ファイルの書き込み処理に違いはありません。
また、AngularJSではHTMLの要素を処理する処理はコントローラで記述することは推奨されていません。本来であれば、ディレクティブなどを別途作成する方が望ましいですが、処理の簡略化と説明の都合のためコントローラ内に記述しています。
続いて、画像ファイルを表示します。cdvfileプロトコルを使えばHTMLのIMGタグに保存したパスを指定する事で可能で、使用するHTMLテンプレートがリスト9のようになります。cdvfileプロトコルを使わなくてもJavaScriptでData URL形式などを使えば可能ですが、cdvfileプロトコルを使うよりも何倍も手間がかかります。
AngularJSではng-srcに画像パスを設定すると自動的にsrcタグに同じパスが設定されますので、img_pathという変数に実際のパスを設定すれば自動的に画像が表示されます。
<img id="img_path" ng-src="{{img_path}}" width="100%">
画像を表示する際に実行する処理がリスト10になります。参考までにjQueryでの設定方法も示します。
$scope.img_path = "cdvfile://localhost/cache/" + $scope.filename;
// $('#img_path').attr('src',"cdvfile://localhost/cache/" + $scope.filename); と同様
また、AngularJS独自の制限になりますが、URLなどをIMG要素のsrc属性に指定する場合には、あらかじめ指定したプロトコル以外では自動的にサニタイズ処理が行われてしまい、正常に表示されないという問題が発生します。そのために、モジュールを作成する箇所にて、リスト11のような記述の追加が必要です。
var module = angular.module('main',[]);
// (省略)
module.config(function($compileProvider) {
$compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|mailto|cdvfile):/);
}
最後に
前回と今回でファイルプラグインを紹介しました。アプリ内のファイルを扱えることは、オフライン対応などを行う上で必須となる機能です。実際にはネットワークからダウンロードしたファイルを扱ったり、ローカルのファイルをネットワークへとアップロードしたりするなど、その他のプラグインと連携して利用するケースが多いと思います。また、スマホで撮った写真、映像などと連携したアプリを作る際にも必要になる事でしょう。本格的なアプリを作成する上でファイル関連操作は必ず必要となる機能ですので、ぜひ使い方を覚えてアプリ作成に役立てていただけると幸いです。
