Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular-file-upload with ngImgCrop

I'm using (ngImgCrop) to crop an image and then upload the cropped image to server using (angular-file-upload).

I can get the $dataURI from the "on-change" option in ngImgCrop. But I need a File instace to call $upload. How can I get the File instance of the cropped image in order to upload :

        $scope.upload = $upload.upload({
            url: '/api/fileupload',
            file: [**file cropped here**]
        }).progress(function (evt) {
            //
        }).success(function (data, status, headers, config) {
            //
        });
like image 212
rayashi Avatar asked Sep 22 '14 19:09

rayashi


2 Answers

I guess you'll find a proper answer in this method. I found it in Github, in the angular-file-upload issues page (https://github.com/nervgh/angular-file-upload/issues/208):

/**
   * 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});
  };

You should be able to get a file instance doing something like this:

var blob = dataURItoBlob($scope.croppedImage);

I don't know if it works in the good way, but it seems.

like image 182
Rubén Jiménez Avatar answered Oct 13 '22 07:10

Rubén Jiménez


try something like:

 var uploader = $scope.uploader = new FileUploader({
        url: '/saveImagePath',
        autoUpload: false
    });

angular.element(document.querySelector('#fileInput')).on('change',handleFileSelect);

var handleFileSelect=function(evt) {
      var file=evt.currentTarget.files[0];
      var reader = new FileReader();
      reader.onload = function (evt) {
        $scope.$apply(function($scope){
          $scope.myImage=evt.target.result;
        });
      };
      reader.readAsDataURL(file);
    };

the uploader doesn't support base64 images so you'll need to convert the cropped image from base64 to blob

function base64ToBlob(base64Data, contentType) {
        contentType = contentType || '';
        var sliceSize = 1024;
        var byteCharacters = atob(base64Data);
        var bytesLength = byteCharacters.length;
        var slicesCount = Math.ceil(bytesLength / sliceSize);
        var byteArrays = new Array(slicesCount);

        for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
            var begin = sliceIndex * sliceSize;
            var end = Math.min(begin + sliceSize, bytesLength);

            var bytes = new Array(end - begin);
            for (var offset = begin, i = 0 ; offset < end; ++i, ++offset) {
                bytes[i] = byteCharacters[offset].charCodeAt(0);
            }
            byteArrays[sliceIndex] = new Uint8Array(bytes);
        }
        return new Blob(byteArrays, { type: contentType });
    }

you have to manually attach the files to the queue like this:

$scope.submit = function () {
         var file = base64ToBlob($scope.currentPortfolio.croppedImage.replace('data:image/png;base64,',''), 'image/jpeg');
        uploader.addToQueue(file);
        uploader.uploadAll();

    };

in the server side, you got two types of files one posted as HTML file and another un base64 which is the cropped image.

like image 40
pedrommuller Avatar answered Oct 13 '22 09:10

pedrommuller