AngularJS file upload from ngThumb directive (with angular-file-upload)
Asked Answered
G

4

24

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!!

Genisia answered 29/9, 2015 at 9:46 Comment(4)
Can you explain your problem in more detail? What does "load back the images" and "edit mode" mean?Rent
When you say 'load back' do you mean how to retrieve them from the database and make them available for loading into the canvas? How are you retrieving the images from the database?Skeg
Would be interesting if one of the answers were right?Rent
hi do you have a source code how to save the image on DB?? im really confuse how to angular file upload works??Serene
O
2

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>.

Opportina answered 7/10, 2015 at 17:39 Comment(0)
O
2

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

Outside answered 10/10, 2015 at 10:41 Comment(0)
D
2

// 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>
Dunagan answered 13/10, 2015 at 7:31 Comment(0)
R
2

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!

Rent answered 13/10, 2015 at 19:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.