diff --git a/bower.json b/bower.json
index 11f82fd6b5..9738f46d4c 100644
--- a/bower.json
+++ b/bower.json
@@ -7,12 +7,13 @@
     "angular": "~1.5.0",
     "angular-animate": "~1.5.0",
     "angular-bootstrap": "~1.2.1",
-    "angular-file-upload": "~2.2.0",
     "angular-messages": "~1.5.0",
     "angular-mocks": "~1.5.0",
     "angular-resource": "~1.5.0",
     "angular-ui-router": "~0.2.18",
     "bootstrap": "~3.3.6",
+    "ng-file-upload": "^12.1.0",
+    "ng-img-crop": "ngImgCrop#^0.3.2",
     "owasp-password-strength-test": "~1.3.0"
   },
   "overrides": {
diff --git a/config/assets/default.js b/config/assets/default.js
index a83f0ba00e..7d4fdca421 100644
--- a/config/assets/default.js
+++ b/config/assets/default.js
@@ -9,6 +9,7 @@ module.exports = {
         // bower:css
         'public/lib/bootstrap/dist/css/bootstrap.css',
         'public/lib/bootstrap/dist/css/bootstrap-theme.css',
+        'public/lib/ng-img-crop/compile/unminified/ng-img-crop.css'
         // endbower
       ],
       js: [
@@ -16,7 +17,8 @@ module.exports = {
         'public/lib/angular/angular.js',
         'public/lib/angular-animate/angular-animate.js',
         'public/lib/angular-bootstrap/ui-bootstrap-tpls.js',
-        'public/lib/angular-file-upload/dist/angular-file-upload.min.js',
+        'public/lib/ng-file-upload/ng-file-upload.js',
+        'public/lib/ng-img-crop/compile/unminified/ng-img-crop.js',
         'public/lib/angular-messages/angular-messages.js',
         'public/lib/angular-mocks/angular-mocks.js',
         'public/lib/angular-resource/angular-resource.js',
diff --git a/modules/core/client/app/config.js b/modules/core/client/app/config.js
index b5476213eb..3231e35e97 100644
--- a/modules/core/client/app/config.js
+++ b/modules/core/client/app/config.js
@@ -5,7 +5,7 @@
 
   var service = {
     applicationModuleName: applicationModuleName,
-    applicationModuleVendorDependencies: ['ngResource', 'ngAnimate', 'ngMessages', 'ui.router', 'ui.bootstrap', 'angularFileUpload'],
+    applicationModuleVendorDependencies: ['ngResource', 'ngAnimate', 'ngMessages', 'ui.router', 'ui.bootstrap', 'ngFileUpload', 'ngImgCrop'],
     registerModule: registerModule
   };
 
diff --git a/modules/users/client/controllers/settings/change-profile-picture.client.controller.js b/modules/users/client/controllers/settings/change-profile-picture.client.controller.js
index 5f5afd8931..411b62a14e 100644
--- a/modules/users/client/controllers/settings/change-profile-picture.client.controller.js
+++ b/modules/users/client/controllers/settings/change-profile-picture.client.controller.js
@@ -5,82 +5,52 @@
     .module('users')
     .controller('ChangeProfilePictureController', ChangeProfilePictureController);
 
-  ChangeProfilePictureController.$inject = ['$scope', '$timeout', '$window', 'Authentication', 'FileUploader'];
+  ChangeProfilePictureController.$inject = ['$timeout', 'Authentication', 'Upload'];
 
-  function ChangeProfilePictureController($scope, $timeout, $window, Authentication, FileUploader) {
+  function ChangeProfilePictureController($timeout, Authentication, Upload) {
     var vm = this;
 
     vm.user = Authentication.user;
-    vm.imageURL = vm.user.profileImageURL;
-    vm.uploadProfilePicture = uploadProfilePicture;
+    vm.fileSelected = false;
 
-    vm.cancelUpload = cancelUpload;
-    // Create file uploader instance
-    vm.uploader = new FileUploader({
-      url: 'api/users/picture',
-      alias: 'newProfilePicture',
-      onAfterAddingFile: onAfterAddingFile,
-      onSuccessItem: onSuccessItem,
-      onErrorItem: onErrorItem
-    });
-
-    // Set file uploader image filter
-    vm.uploader.filters.push({
-      name: 'imageFilter',
-      fn: function (item, options) {
-        var type = '|' + item.type.slice(item.type.lastIndexOf('/') + 1) + '|';
-        return '|jpg|png|jpeg|bmp|gif|'.indexOf(type) !== -1;
-      }
-    });
+    vm.upload = function (dataUrl, name) {
+      vm.success = vm.error = null;
 
-    // Called after the user selected a new picture file
-    function onAfterAddingFile(fileItem) {
-      if ($window.FileReader) {
-        var fileReader = new FileReader();
-        fileReader.readAsDataURL(fileItem._file);
-
-        fileReader.onload = function (fileReaderEvent) {
-          $timeout(function () {
-            vm.imageURL = fileReaderEvent.target.result;
-          }, 0);
-        };
-      }
-    }
+      Upload.upload({
+        url: 'api/users/picture',
+        data: {
+          newProfilePicture: Upload.dataUrltoBlob(dataUrl, name)
+        }
+      }).then(function (response) {
+        $timeout(function () {
+          onSuccessItem(response.data);
+        });
+      }, function (response) {
+        if (response.status > 0) onErrorItem(response.data);
+      }, function (evt) {
+        vm.progress = parseInt(100.0 * evt.loaded / evt.total, 10);
+      });
+    };
 
     // Called after the user has successfully uploaded a new picture
-    function onSuccessItem(fileItem, response, status, headers) {
+    function onSuccessItem(response) {
       // Show success message
       vm.success = true;
 
       // Populate user object
       vm.user = Authentication.user = response;
 
-      // Clear upload buttons
-      cancelUpload();
+      // Reset form
+      vm.fileSelected = false;
+      vm.progress = 0;
     }
 
     // Called after the user has failed to uploaded a new picture
-    function onErrorItem(fileItem, response, status, headers) {
-      // Clear upload buttons
-      cancelUpload();
+    function onErrorItem(response) {
+      vm.fileSelected = false;
 
       // Show error message
       vm.error = response.message;
     }
-
-    // Change user profile picture
-    function uploadProfilePicture() {
-      // Clear messages
-      vm.success = vm.error = null;
-
-      // Start upload
-      vm.uploader.uploadAll();
-    }
-
-    // Cancel the upload process
-    function cancelUpload() {
-      vm.uploader.clearQueue();
-      vm.imageURL = vm.user.profileImageURL;
-    }
   }
 }());
diff --git a/modules/users/client/css/users.css b/modules/users/client/css/users.css
index 9bbc8961b5..3a196c58f2 100644
--- a/modules/users/client/css/users.css
+++ b/modules/users/client/css/users.css
@@ -34,3 +34,8 @@
   min-height: 150px;
   max-height: 150px;
 }
+.cropArea {
+    background: #E4E4E4;
+    width: 300px;
+    height: 300px;
+}
diff --git a/modules/users/client/views/settings/change-profile-picture.client.view.html b/modules/users/client/views/settings/change-profile-picture.client.view.html
index ed4b2cc810..721c34bb46 100644
--- a/modules/users/client/views/settings/change-profile-picture.client.view.html
+++ b/modules/users/client/views/settings/change-profile-picture.client.view.html
@@ -2,17 +2,26 @@
   <div class="col-xs-offset-1 col-xs-10 col-md-offset-3 col-md-4">
     <form class="signin form-horizontal">
       <fieldset>
+        <div ng-show="vm.fileSelected" class="text-center form-group">
+          <p>Crop your picture then press upload below:</p>
+          <div ngf-drop ng-model="picFile" ngf-pattern="image/*" class="cropArea">
+            <img-crop image="picFile | ngfDataUrl" result-image="croppedDataUrl" ng-init="croppedDataUrl=''"></img-crop>
+          </div>
+        </div>
         <div class="form-group text-center">
-          <img ng-src="{{vm.imageURL}}" alt="{{vm.user.displayName}}" class="img-thumbnail user-profile-picture">
+          <img ng-src="{{vm.fileSelected ? croppedDataUrl : vm.user.profileImageURL}}" alt="{{vm.user.displayName}}" class="img-thumbnail user-profile-picture" ngf-drop>
+        </div>
+        <div ng-show="!vm.fileSelected" class="text-center form-group">
+          <button class="btn btn-default btn-file" ngf-select="vm.fileSelected = true; vm.success = null" ng-model="picFile" accept="image/*">Select Picture</button>
         </div>
-        <div class="text-center form-group" ng-hide="vm.uploader.queue.length">
-          <span class="btn btn-default btn-file">
-              Select Image <input type="file" nv-file-select uploader="vm.uploader">
-          </span>
+        <div ng-show="vm.fileSelected" class="text-center form-group">
+          <button class="btn btn-primary" ng-click="vm.upload(croppedDataUrl, picFile.name)">Upload</button>
+          <button class="btn btn-default" ng-click="vm.fileSelected = false">Cancel</button>
         </div>
-        <div class="text-center form-group" ng-show="vm.uploader.queue.length">
-          <button class="btn btn-primary" ng-click="vm.uploadProfilePicture();">Upload</button>
-          <button class="btn btn-default" ng-click="vm.cancelUpload();">Cancel</button>
+        <div ng-show="vm.fileSelected" class="progress text-center">
+          <div class="progress-bar" role="progressbar" aria-valuenow="{{vm.progress}}" aria-valuemin="0" aria-valuemax="100" style="width:{{vm.progress}}%" ng-bind="vm.progress + '%'">
+            <span class="sr-only">{{vm.progress}}% Complete</span>
+          </div>
         </div>
         <div ng-show="vm.success" class="text-center text-success">
           <strong>Profile Picture Changed Successfully</strong>