AngularJS Client-side Image Optimization

Hi, friends in this post we going to see how to make client-side image optimization using AngularJS. The main benefit of AngularJS is its capacity to perform client-side processing of the image, reducing the size of data to be sent to the server. This is especially helpful for websites targeted to users of mobile devices. It provides, for instance, uploading to the server images taken with the built-in camera. An image of this type can be large Megabytes in size, with a resolution over big to be exposed on a web page. Among AngularJS, it is conceivable to change the scale, and optionally the quality of the image, to reduce the size by up to 60%.
Also, AngularJS load does whatsoever image processing mechanism is accessible to the client to execute this processing of the image: html5, flash or Silverlight etc.. making it compatible with virtually any type of client.
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
<!doctype html> <html class="no-js"> <head> <meta charset="UTF-8"> <title>SoftAOX | AngularJS Client-side Image Optimization</title> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <style> .upload-optimized-zone { height: auto; min-height: 300px; border-width: 2px; margin-bottom: 20px; } .upload-optimized-zone { color: #ccc; border-style: dashed; border-color: #ccc; line-height: 200px; text-align: center } .image-preview-input input[type=file] { position: absolute; top: 0; right: 0; margin: 0; padding: 0; font-size: 20px; cursor: pointer; opacity: 0; filter: alpha(opacity=0); } </style> </head> <body> <div ng-app="myapp" ng-controller="controller"> <div class="container"> <br /> <h1 align="center">AngularJS Client-side Image Optimization</h1> <div class="row"> <div class="col-md-12"> <div class="panel panel-default"> <div class="panel-heading"><strong>Upload Images</strong></div> <div class="panel-body"> <div class="input-group"> <span class="input-group-btn"> <div class="btn btn-default image-preview-input"> <span class="glyphicon glyphicon-folder-open"></span> <span>Browse</span> <input type="file" accept="image/*" ng-model="img_quee" image="img_quee" resize-max-height="500" resize-max-width="500" resize-quality="0.6" resize-type="image/jpg" multiple ng-image-compress/> </div> </span> </div> <br /> <h4>Optimized Output Image</h4> <div class="upload-optimized-zone"> <img ng-src="{{part.optimized.dataURL}}" ng-repeat="part in img_quee" /> </div> <br /> </div> </div> </div> </div> </div> </div> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script> <script src="myapp.js"></script> <script> 'use strict'; var app = angular.module('myapp', ['ngImageCompress']); app.controller('controller', function($scope) { }) </script> </body> </html> |
myapp.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
// myapp image optimize Script 'use strict'; (function(window, angular, undefined) { 'use strict'; angular.module('ngImageCompress', []) .directive('ngImageCompress', ['$q', function($q) { var URL = window.URL || window.webkitURL; var getspace_Resize = function() { var space_ResizeId = 'fileupload-resize-area'; var space_Resize = document.getElementById(space_ResizeId); if (!space_Resize) { space_Resize = document.createElement('canvas'); space_Resize.id = space_ResizeId; space_Resize.style.visibility = 'hidden'; document.body.appendChild(space_Resize); } return space_Resize; }; //Gets an Image Object can be (jpg or png) and delivers a new Image Object optimized var jicOptimize = function(sourceImgObj, options) { var outputFormat = options.resizeType; var quality = options.resizeQuality * 100 || 60; var mimeType = 'image/jpeg'; if (outputFormat !== undefined && outputFormat === 'png') { mimeType = 'image/png'; } var maxHeight = options.resizeMaxHeight || 230; var maxWidth = options.resizeMaxWidth || 150; var height = sourceImgObj.height; var width = sourceImgObj.width; // determine the width and height, compelling the dimensions if (width > height) { if (width > maxWidth) { height = Math.round(height *= maxWidth / width); width = maxWidth; } } else { if (height > maxHeight) { width = Math.round(width *= maxHeight / height); height = maxHeight; } } var cvs = document.createElement('canvas'); cvs.width = width; cvs.height = height; var ctx = cvs.getContext('2d').drawImage(sourceImgObj, 0, 0, width, height); var lat_img_info = cvs.toDataURL(mimeType, quality / 100); var img_object_res = new Image(); img_object_res.src = lat_img_info; return img_object_res.src; }; var resizeImage = function(img_real, options) { var maxHeight = options.resizeMaxHeight || 230; var maxWidth = options.resizeMaxWidth || 150; var quality = options.resizeQuality || 0.6; var type = options.resizeType || 'image/jpg'; var canvas = getspace_Resize(); var height = img_real.height; var width = img_real.width; // determine the width and height, compelling the dimensions if (width > height) { if (width > maxWidth) { height = Math.round(height *= maxWidth / width); width = maxWidth; } } else { if (height > maxHeight) { width = Math.round(width *= maxHeight / height); height = maxHeight; } } canvas.width = width; canvas.height = height; var ctx = canvas.getContext('2d'); ctx.drawImage(img_real, 0, 0, width, height); return canvas.toDataURL(type, quality); }; var create_img = function(url, callback) { var image = new Image(); image.onload = function() { callback(image); }; image.src = url; }; var fileToDataURL = function(file) { var deferred = $q.defer(); var reader = new FileReader(); reader.onload = function(e) { deferred.resolve(e.target.result); }; reader.readAsDataURL(file); return deferred.promise; }; return { restrict: 'A', scope: { image: '=', resizeMaxHeight: '@?', resizeMaxWidth: '@?', resizeQuality: '@?', resizeType: '@?' }, link: function postLink(scope, element, attrs) { var doResizing = function(img_outcome, callback) { create_img(img_outcome.url, function(image) { var dataURLoptimized = jicOptimize(image, scope); img_outcome.optimized = { dataURL: dataURLoptimized, type: dataURLoptimized.match(/:(.+\/.+);/)[1] }; callback(img_outcome); }); }; var applyScope = function(img_outcome) { scope.$apply(function() { if (attrs.multiple) { scope.image.push(img_outcome); } else { scope.image = img_outcome; } }); }; element.bind('change', function(evt) { if (attrs.multiple) { scope.image = []; } var files = evt.target.files; for (var i = 0; i < files.length; i++) { // generate a result object for every file in files var img_outcome = { file: files[i], url: URL.createObjectURL(files[i]) }; fileToDataURL(files[i]).then(function(dataURL) { img_outcome.dataURL = dataURL; }); if (scope.resizeMaxHeight || scope.resizeMaxWidth) { doResizing(img_outcome, function(img_outcome) { applyScope(img_outcome); }); } else { applyScope(img_outcome); } } }); } }; } ]); })(window, window.angular); |
Mraj
Creative Designer & Developer specialist by the spirit and a loving blogger by thoughts. If you have any questions let me drop an email with the article name to the following email id: [email protected]