読者です 読者をやめる 読者になる 読者になる

Septeni Engineer's Blog

セプテーニエンジニアが綴る技術ブログ

HTML5 File API とAngularJSで画像をアップロード前にプレビュー

こんばんは、ゆあさです。

HTML5で追加されたFile APIを使うと、ユーザーが選択した画像ファイルをブラウザ上でプレビュー表示する機能を簡単に実装することができます。
そこでAngularJSを使ったアプリケーションで画像ファイルプレビュー機能の実装するサンプルを紹介したいと思います。

今回は外部のモジュールを使用せず必要最低限の機能のDirectiveとControllerを実装していきます。

Directiveの実装

まずはControllerのscopeからユーザーが選択したファイルを参照できるようにするためのDirectiveの実装です。

myApp.directive("fileModel", ["$parse", function ($parse) {
    return {
        restrict: "A",
        link: function (scope, element, attrs) {
            var model = $parse(attrs.fileModel);
            element.bind("change", function () {
                scope.$apply(function () {
                    model.assign(scope, element[0].files[0]);
                });
            });
        }
    };
}]);

Controllerの実装

あとはController側でファイルの選択をwatchし、File APIを使用して画像ファイルを読み込む部分を実装します。

myApp.controller("myController", ["$scope", function ($scope) {
    $scope.$watch("imageFile", function (imageFile) {
        $scope.imageFileSrc = undefined;
        if (!imageFile || !imageFile.type.match("image.*")) {
            return;
        }
        var reader = new FileReader();
        reader.onload = function () {
            $scope.$apply(function () {
                $scope.imageFileSrc = reader.result;
            });
        };
        reader.readAsDataURL(imageFile);
    });
}]);

Viewの実装

View側の実装は下記のようになります。

<div ng-app="myApp">
    <div ng-controller="myController">
        <input type="file" file-model="imageFile"/>
        <br/>
        <img ng-if="imageFileSrc" ng-src="{{imageFileSrc}}" style="max-width: 300px"/>
    </div>
</div>

デモ

https://jsfiddle.net/ko_yuasa/1tpevwot/

 

上記のように最低限の機能であれば外部モジュールを使わずにAngularJSとFile APIの組み合わせで簡単に画像プレビュー機能を実現することができました。
現状Controllerでやっている画像ファイルの読み込み部分もServiceに切り出して実装するなどすればさらに再利用性を高めることもできそうですね。

それではまた。

参考

http://php.o0o0.jp/article/jquery-preview_thumbnail
http://uncorkedstudios.com/blog/multipartformdata-file-upload-with-angularjs
http://flabo.io/code/20141031/01-angularjs-compare-file-upload/