I am using Angular-File-Upload to upload file to server. Everything works fine and the file can be saved in DB.
The question is, how can I load back the images that I saved when in edit mode?
This is the directive to create canvas
when upload the pic
'use strict';
myApp
.directive('ngThumb', ['$window', function($window) {
var helper = {
support: !!($window.FileReader && $window.CanvasRenderingContext2D),
isFile: function(item) {
return angular.isObject(item) && item instanceof $window.File;
},
isImage: function(file) {
var type = '|' + file.type.slice(file.type.lastIndexOf('/') + 1) + '|';
return '|jpg|png|jpeg|bmp|gif|'.indexOf(type) !== -1;
}
};
return {
restrict: 'A',
template: '<canvas/>',
link: function(scope, element, attributes) {
if (!helper.support) return;
var params = scope.$eval(attributes.ngThumb);
if (!helper.isFile(params.file)) return;
if (!helper.isImage(params.file)) return;
var canvas = element.find('canvas');
var reader = new FileReader();
reader.onload = onLoadFile;
reader.readAsDataURL(params.file);
function onLoadFile(event) {
var img = new Image();
img.onload = onLoadImage;
img.src = event.target.result;
}
function onLoadImage() {
var width = params.width || this.width / this.height * params.height;
var height = params.height || this.height / this.width * params.width;
canvas.attr({ width: width, height: height });
canvas[0].getContext('2d').drawImage(this, 0, 0, width, height);
}
}
};
}]);
This is an html snippet that load canvas when there is an upload:
<div class="table-responsive" ng-hide="!uploaderImages.queue.length">
<table class="table">
<thead>
<tr>
<th width="50%">Name</th>
<th ng-show="uploaderImages.isHTML5">Size</th>
<th ng-show="uploaderImages.isHTML5">Progress</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in uploaderImages.queue">
<td><strong>{{ item.file.name }}</strong>
<div ng-show="uploaderImages.isHTML5" ng-thumb="{ file: item._file, height: 100 }"></div>
</td>
<td ng-show="uploaderImages.isHTML5" nowrap>{{ item.file.size/1024/1024|number:2 }} MB</td>
<td ng-show="uploaderImages.isHTML5">
<div class="progress progress-xs 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-danger btn-xs" ng-click="item.remove()">
<span class="glyphicon glyphicon-trash"></span> Remove
</button></td>
</tr>
</tbody>
</table>
</div>
Thanks!!
Since the uploader is working fine already and you're able to save the images into the database, all you need to do is to show the uploaded images as thumbnails on a canvas.
That can be done using some jQuery like this:
// source of a large image - replace this with the URL of the uploaded image (served from the database)
var IMAGE_SRC = "http://cdn-media-1.lifehack.org/wp-content/files/2014/09/activities-on-the-beach.jpg";
// set the height for the thumbnail - your uploader currently has 100
var height = 100;
function drawImage() {
// create a new Image object
var img = new Image();
// set up the onLoad handler on the image object to draw the thumbnail into the canvas
img.onload = function() {
// calculate the thumbnail width for the fixed height above, respecting the image aspect ratio
var width = this.width / this.height * height;
// set the dimensions on the canvas
$("canvas").attr({
width: width,
height: height
});
// draw the image from the loaded image object
$("canvas")[0].getContext("2d").drawImage(img, 0, 0, width, height);
};
// set the source of the image object to the URL of the uploaded image (served from the database)
img.src = IMAGE_SRC;
}
// Do all of this when the button is clicked
$("button").click(drawImage);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Load image into Canvas</button>
<br />
<br />
<canvas></canvas>
The same code could also be converted into another angular directive - something like <uploaded-image></uploaded-image>
.
Writing down a simple directive to preview the returned images is quite easy. More or less is the a simplified version of the ngThumb
directive you have provided.
angular.module('components', [])
.directive('imgPreview', [function () {
return {
restrict: 'E',
template: '<canvas/>',
replace: true,
link: function (scope, element, attrs) {
var myCanvas = element[0];
var ctx = myCanvas.getContext('2d');
var img = new Image;
img.onerror = function () {
throw new Error("Image can't be loaded");
}
img.onload = function () {
myCanvas.width = img.width;
myCanvas.height = img.height;
ctx.drawImage(img, 0, 0); // Or at whatever offset you like
};
img.src = attrs.image;
}
}
}]);
Demo
// source of a large image - replace this with the URL of the uploaded image (served from the database)
var IMAGE_SRC = "http://cdn-media-1.lifehack.org/wp-content/files/2014/09/activities-on-the-beach.jpg";
// set the height for the thumbnail - your uploader currently has 100
var height = 100;
function drawImage() {
// create a new Image object
var img = new Image();
// set up the onLoad handler on the image object to draw the thumbnail into the canvas
img.onload = function() {
// calculate the thumbnail width for the fixed height above, respecting the image aspect ratio
var width = this.width / this.height * height;
// set the dimensions on the canvas
$("canvas").attr({
width: width,
height: height
});
// draw the image from the loaded image object
$("canvas")[0].getContext("2d").drawImage(img, 0, 0, width, height);
};
// set the source of the image object to the URL of the uploaded image (served from the database)
img.src = IMAGE_SRC;
}
// Do all of this when the button is clicked
$("button").click(drawImage);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Load image into Canvas</button>
<br />
<br />
<canvas></canvas>
If I understand your question right, then I think you need to upload a blob (so after editing an image in canvas you have a Data URI. And you need to convert this into a Blob which you can upload!
Here is the solution I used for uploading a cropped image with angular-file-upload:
https://github.com/nervgh/angular-file-upload/issues/208#issuecomment-116344239
You need to use
uploader.onBeforeUploadItem
to overwrite the actual file = item._file
!
PS: There is also a function for converting 'DataURI' to 'Blob' in the given link!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With