Skip to content

Instantly share code, notes, and snippets.

@brianfeister
Last active May 27, 2020 02:37
Show Gist options
  • Save brianfeister/56a1c6c77cd5928a1c53 to your computer and use it in GitHub Desktop.
Save brianfeister/56a1c6c77cd5928a1c53 to your computer and use it in GitHub Desktop.
Angular Upload with Image Crop
angular.module('cropAndUpload', [
'angularFileUpload',
'ngImgCrop'
])
angular.module('cropAndUpload')
.controller('Ctrl', function ($scope, FileUploader) {
var uploader = $scope.uploader = new FileUploader({
url: '/api/users/photo'
});
// FILTERS
uploader.filters.push({
name: 'imageFilter',
fn: function(item /*{File|FileLikeObject}*/, options) {
var type = '|' + item.type.slice(item.type.lastIndexOf('/') + 1) + '|';
return '|jpg|png|jpeg|bmp|gif|'.indexOf(type) !== -1;
}
});
// CALLBACKS
/**
* Show preview with cropping
*/
uploader.onAfterAddingFile = function(item) {
// $scope.croppedImage = '';
item.croppedImage = '';
var reader = new FileReader();
reader.onload = function(event) {
$scope.$apply(function(){
item.image = event.target.result;
});
};
reader.readAsDataURL(item._file);
};
/**
* Upload Blob (cropped image) instead of file.
* @see
* https://developer.mozilla.org/en-US/docs/Web/API/FormData
* https://github.com/nervgh/angular-file-upload/issues/208
*/
uploader.onBeforeUploadItem = function(item) {
var blob = dataURItoBlob(item.croppedImage);
item._file = blob;
};
/**
* Converts data uri to Blob. Necessary for uploading.
* @see
* http://stackoverflow.com/questions/4998908/convert-data-uri-to-file-then-append-to-formdata
* @param {String} dataURI
* @return {Blob}
*/
var dataURItoBlob = function(dataURI) {
var binary = atob(dataURI.split(',')[1]);
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
var array = [];
for(var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
return new Blob([new Uint8Array(array)], {type: mimeString});
};
uploader.onWhenAddingFileFailed = function(item /*{File|FileLikeObject}*/, filter, options) {
console.info('onWhenAddingFileFailed', item, filter, options);
};
uploader.onAfterAddingAll = function(addedFileItems) {
console.info('onAfterAddingAll', addedFileItems);
};
uploader.onProgressItem = function(fileItem, progress) {
console.info('onProgressItem', fileItem, progress);
};
uploader.onProgressAll = function(progress) {
console.info('onProgressAll', progress);
};
uploader.onSuccessItem = function(fileItem, response, status, headers) {
console.info('onSuccessItem', fileItem, response, status, headers);
};
uploader.onErrorItem = function(fileItem, response, status, headers) {
console.info('onErrorItem', fileItem, response, status, headers);
};
uploader.onCancelItem = function(fileItem, response, status, headers) {
console.info('onCancelItem', fileItem, response, status, headers);
};
uploader.onCompleteItem = function(fileItem, response, status, headers) {
console.info('onCompleteItem', fileItem, response, status, headers);
};
uploader.onCompleteAll = function() {
console.info('onCompleteAll');
};
console.info('uploader', uploader);
});
<div class="container" ng-controller="Ctrl">
<div class="row">
<div class="col-sm-12">
<div class="row" nv-file-drop="" uploader="uploader">
<div class="col-md-3">
<h3>Select files</h3>
<div ng-show="uploader.isHTML5">
<!-- 3. nv-file-over uploader="link" over-class="className" -->
<div class="well my-drop-zone" nv-file-over="" uploader="uploader">
Base drop zone
</div>
<!-- Example: nv-file-drop="" uploader="{Object}" options="{Object}" filters="{String}" -->
<div nv-file-drop="" uploader="uploader" options="{ url: '/foo' }">
<div nv-file-over="" uploader="uploader" over-class="another-file-over-class" class="well my-drop-zone">
Another drop zone with its own settings
</div>
</div>
</div>
<!-- Example: nv-file-select="" uploader="{Object}" options="{Object}" filters="{String}" -->
<input type="file" nv-file-select="" uploader="uploader" multiple /><br/>
</div>
<div class="col-md-9" style="margin-bottom: 40px">
<h2>Uploads only images (with canvas preview)</h2>
<h3>The queue</h3>
<p>Queue length: {{ uploader.queue.length }}</p>
<table class="table">
<thead>
<tr>
<th width="50%">Name</th>
<th ng-show="uploader.isHTML5">Size</th>
<th ng-show="uploader.isHTML5">Progress</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in uploader.queue">
<td>
<strong>{{ item.file.name }}</strong>
<div class="cropArea">
<img-crop image="item.image" result-image="item.croppedImage"></img-crop>
</div>
<div>Cropped Image:</div>
<div><img ng-src="{{item.croppedImage}}" /></div>
</td>
<td ng-show="uploader.isHTML5" nowrap>{{ item.file.size/1024/1024|number:2 }} MB</td>
<td ng-show="uploader.isHTML5">
<div class="progress" style="margin-bottom: 0;">
<div class="progress-bar" role="progressbar" ng-style="{ 'width': item.progress + '%' }"></div>
</div>
</td>
<td class="text-center">
<span ng-show="item.isSuccess"><i class="glyphicon glyphicon-ok"></i></span>
<span ng-show="item.isCancel"><i class="glyphicon glyphicon-ban-circle"></i></span>
<span ng-show="item.isError"><i class="glyphicon glyphicon-remove"></i></span>
</td>
<td nowrap>
<button type="button" class="btn btn-success btn-xs" ng-click="item.upload()" ng-disabled="item.isReady || item.isUploading || item.isSuccess">
<span class="glyphicon glyphicon-upload"></span> Upload
</button>
<button type="button" class="btn btn-warning btn-xs" ng-click="item.cancel()" ng-disabled="!item.isUploading">
<span class="glyphicon glyphicon-ban-circle"></span> Cancel
</button>
<button type="button" class="btn btn-danger btn-xs" ng-click="item.remove()">
<span class="glyphicon glyphicon-trash"></span> Remove
</button>
</td>
</tr>
</tbody>
</table>
<div>
<div>
Queue progress:
<div class="progress" style="">
<div class="progress-bar" role="progressbar" ng-style="{ 'width': uploader.progress + '%' }"></div>
</div>
</div>
<button type="button" class="btn btn-success btn-s" ng-click="uploader.uploadAll()" ng-disabled="!uploader.getNotUploadedItems().length">
<span class="glyphicon glyphicon-upload"></span> Upload all
</button>
<button type="button" class="btn btn-warning btn-s" ng-click="uploader.cancelAll()" ng-disabled="!uploader.isUploading">
<span class="glyphicon glyphicon-ban-circle"></span> Cancel all
</button>
<button type="button" class="btn btn-danger btn-s" ng-click="uploader.clearQueue()" ng-disabled="!uploader.queue.length">
<span class="glyphicon glyphicon-trash"></span> Remove all
</button>
</div>
</div>
</div>
</div>
</div>
@hartjo
Copy link

hartjo commented Jun 21, 2015

cant get my ngcrop and file upload to work together

@eugene-d
Copy link

Works fine

@s875515
Copy link

s875515 commented Dec 22, 2015

Thanks a lot. It work for me.

@guptaaman2011
Copy link

can u provide the working fiddle and how to send the image to rest service and to server

@mandadimuralidharreddy
Copy link

Here is codepen and PHP back end code
http://codepen.io/muralidharm/pen/gMmJPN

@matheusramos
Copy link

Thanks! Exactly what I was looking for :)

@RobbertWolfs
Copy link

Exactly what I need 💯

@manishbaytech
Copy link

Thanks a Lot !!!

@Marioum
Copy link

Marioum commented May 2, 2017

Great!
Did the progress bar work for you?

@Marioum
Copy link

Marioum commented May 2, 2017

Solved 💃 Just need to add bootstrap libs!
Thank you!

@rhclayto
Copy link

You can try using uiCropper, a fork of imgCrop - https://github.com/CrackerakiUA/ui-cropper - which can already output blobs. No need to manually convert to blob first. It works great for me.

@ThaMCW360
Copy link

@rhclayto, can You show snippet of your Code, with usage ui-cropper with this plugin?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment