2 * ================================================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ================================================================================
23 angular.module('ecompApp').directive('imageUpload', function factory($q) {
24 var imageMimeRgx = /^image\/[a-zA-Z0-9]*$/;
26 var URL = window.URL || window.webkitURL;
28 var getResizeArea = function () {
29 var resizeAreaId = 'fileupload-resize-area';
31 var resizeArea = document.getElementById(resizeAreaId);
34 resizeArea = document.createElement('canvas');
35 resizeArea.id = resizeAreaId;
36 resizeArea.style.visibility = 'hidden';
37 document.body.appendChild(resizeArea);
43 var resizeImage = function (origImage, options) {
44 var maxHeight = options.resizeMaxHeight || 300;
45 var maxWidth = options.resizeMaxWidth || 250;
46 var quality = options.resizeQuality || 0.7;
47 var type = options.resizeType || 'image/jpg';
49 var canvas = getResizeArea();
51 var height = origImage.height;
52 var width = origImage.width;
54 //image redraw starting points
57 // calculate the width and height, constraining the proportions
59 if (width > maxWidth) {
60 height = Math.round(height *= maxWidth / width);
64 y0 = Math.round((maxHeight - height)/2);
72 if (height > maxHeight) {
73 width = Math.round(width *= maxHeight / height);
76 x0 = Math.round((maxWidth - width)/2);
86 canvas.width = maxWidth;
87 canvas.height = maxHeight;
89 //draw image on canvas
90 var ctx = canvas.getContext('2d');
92 //set background color
93 if(options.backgroundColor){
94 ctx.fillStyle = options.backgroundColor;
95 ctx.fillRect(0,0,maxWidth,maxHeight);
99 ctx.drawImage(origImage, x0, y0, width, height);
101 // get the data from canvas as 70% jpg (or specified type).
102 return canvas.toDataURL(type, quality);
105 var createImage = function(url, callback) {
106 var image = new Image();
107 image.onload = function() {
113 var fileToDataURL = function (file) {
114 var deferred = $q.defer();
115 var reader = new FileReader();
116 reader.onload = function (e) {
117 deferred.resolve(e.target.result);
119 reader.readAsDataURL(file);
120 return deferred.promise;
124 * Image Upload directive
125 * ************************
126 * image-upload: image object , Mandatory
127 * image-upload-resize-max-height: <Number>, Optional (default 300), resize maximum height
128 * image-upload-resize-max-width: <Number>, Optional (default 270), resize maximum width
129 * image-upload-resize-quality: <Number>, Optional, value can be 0.0-1.0 (default 0.7), resize compression quality
130 * image-upload-resize-type: <String>, Optional, (default 'image/jpg'), image mime type
131 * image-upload-api: <Object>, Optional, pass an api reference object and get api.clearFile() function - clear input field and reset form validation
132 * image-upload-background-color: <String> color name, Optional, background color fill if image doesn't fit the whole desired resize area.
134 * in addition, if <input> element is part of <form>, in order to get form validation please set its 'name' attribute and 'ng-model' to get the following field validation errors:
135 * - 'mimeType' : in case the uploaded image is not an image
136 * - 'imageSize' : in case the image size (in bytes) is too large
143 image: '=imageUpload',
144 resizeMaxHeight: '@?imageUploadResizeMaxHeight',
145 resizeMaxWidth: '@?imageUploadResizeMaxWidth',
146 resizeQuality: '@?imageUploadResizeQuality',
147 resizeType: '@?imageUploadResizeType',
148 imageApi: '=?imageUploadApi',
149 backgroundColor: '@?imageUploadBackgroundColor'
151 compile: function compile(tElement, tAttrs, transclude) {
152 return function postLink(scope, iElement, iAttrs, formCtrl) {
153 var doResizing = function(imageResult, callback) {
154 createImage(imageResult.url, function(image) {
155 var dataURL = resizeImage(image, scope);
156 imageResult.resized = {
158 type: dataURL.match(/:(.+\/.+);/)[1]
160 callback(imageResult);
164 var applyScope = function(imageResult) {
165 scope.$apply(function() {
166 //console.log(imageResult);
168 scope.image.push(imageResult);
170 scope.image = imageResult;
174 iElement.bind('change', function (evt) {
175 //when multiple always return an array of images
179 var files = evt.target.files;
180 for(var i = 0; i < files.length; i++) {
181 setInputValidity(files[i]);
183 //create a result object for each file in files
186 url: URL.createObjectURL(files[i])
189 fileToDataURL(files[i]).then(function (dataURL) {
190 imageResult.dataURL = dataURL;
193 if(scope.resizeMaxHeight || scope.resizeMaxWidth) { //resize image
194 doResizing(imageResult, function(imageResult) {
195 applyScope(imageResult);
199 applyScope(imageResult);
204 //API for otter actions
205 scope.imageApi = scope.imageApi || {};
206 scope.imageApi.clearFile = () => {
207 iElement[0].value = '';
212 let setInputValidity = file => {
213 //if form validation supported
215 if(formCtrl && iAttrs.name && formCtrl[iAttrs.name]){
216 formCtrl[iAttrs.name].$setDirty();
217 if(file && file.type && !imageMimeRgx.test(file.type)){
219 formCtrl[iAttrs.name].$setValidity('mimeType', false);
223 if(file && file.size && file.size > 1000000){
225 formCtrl[iAttrs.name].$setValidity('imageSize', false);
230 formCtrl[iAttrs.name].$setValidity('mimeType', true);
231 formCtrl[iAttrs.name].$setValidity('imageSize', true);