Ionic-Angular.js Taking pictures & sending to server: null images

23,122

Solution 1

I resolve with this code :

$scope.getPhoto = function() {
    navigator.camera.getPicture(onSuccess, onFail, { quality: 75, targetWidth: 320,
    targetHeight: 320, destinationType: 0 }); 
    //destination type was a base64 encoding
    function onSuccess(imageData) {
        //preview image on img tag
        $('#image-preview').attr('src', "data:image/jpeg;base64,"+imageData);
        //setting scope.lastPhoto 
        $scope.lastPhoto = dataURItoBlob("data:image/jpeg;base64,"+imageData);
    }
    function onFail(message) {
        alert('Failed because: ' + message);
    }
} 
function dataURItoBlob(dataURI) {
// convert base64/URLEncoded data component to raw binary data held in a string
 var byteString = atob(dataURI.split(',')[1]);
 var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]

 var ab = new ArrayBuffer(byteString.length);
 var ia = new Uint8Array(ab);
 for (var i = 0; i < byteString.length; i++)
 {
    ia[i] = byteString.charCodeAt(i);
 }

 var bb = new Blob([ab], { "type": mimeString });
 return bb;
}

after this use append to your formdata like this:

formData.append('photo', $scope.lastPhoto, $scope.publish.name+'.jpg')

This code run on IOS without problem.

Solution 2

What I ended up doing was to add destinationType: Camera.DestinationType.DATA_URL in the options of the getPhoto function, and that returns a base64 representation of the image, which I then send over to the server and store in a TextField() (Django):

$scope.getPhoto = function() {
Camera.getPicture().then(function(imageURI) {
    console.log(imageURI);
    $scope.lastPhoto = imageURI;
    $scope.upload(); <-- call to upload the pic
},
function(err) {
    console.err(err);
}, {
    quality: 75,
    targetWidth: 320,
    targetHeight: 320,
    saveToPhotoAlbum: false,
    destinationType: Camera.DestinationType.DATA_URL
});
};

Also, when deadling with Base64 images, remember to call the using:

<img ng-src="data:image/jpeg;base64,{{image}}" />

Solution 3

I think your problem lies in the 'Content-Type':undefined. For images, you should use 'Content-Type':'image/jpeg'.

I would also add enctype="multipart/form-data" to the <form>.

Share:
23,122
Claudiu S
Author by

Claudiu S

Updated on April 17, 2020

Comments

  • Claudiu S
    Claudiu S about 4 years

    So I have managed to use a custom directive to upload images to my server, through Angular.js. I have also managed to implement the camera functionality from Cordova. Now I am trying to connect the two, but when sending images to the server, they get stored as null. I believe the problem lies in the fact that I was using an input field to get the image, and it was getting the full Object, and now I am getting just the image path after I take the picture and send it. My problem is, I don't really understand how I could convert the path to an Object, IF that is the problem?

    index.html

    <form class="form-horizontal" role="form">
        <button class="picButton" ng-click="getPhoto()" class="button button-block button-primary">Take Photo</button>
        <img ng-src="{{lastPhoto}}" style="max-width: 100%">
    ...
    </form>
    

    controllers.js

    $scope.getPhoto = function() {
        Camera.getPicture().then(function(imageURI) {
            console.log(imageURI);
            $scope.lastPhoto = imageURI;
            $scope.upload(); <-- call to upload the pic
        },
        function(err) {
            console.err(err);
        }, {
            quality: 75,
            targetWidth: 320,
            targetHeight: 320,
            saveToPhotoAlbum: false
        });
    };
    
    $scope.upload = function() {
        var url = '';
        var fd = new FormData();
    
        //previously I had this
        //angular.forEach($scope.files, function(file){
            //fd.append('image',file)
        //});
    
        fd.append('image', $scope.lastPhoto);
    
        $http.post(url, fd, {
    
            transformRequest:angular.identity,
            headers:{'Content-Type':undefined
            }
        })
        .success(function(data, status, headers){
            $scope.imageURL = data.resource_uri; //set it to the response we get
        })
        .error(function(data, status, headers){
    
        })
    }
    

    When printing $scope.lastPhoto I get the image path: file:///var/mobile/Applications/../tmp/filename.jpg

    EDIT

    Request Headers:

    ------WebKitFormBoundaryEzXidt71U741Mc45
    Content-Disposition: form-data; name="image"
    
    file:///var/mobile/Applications/C65C8030-33BF-4BBB-B2BB-7ECEC86E87A7/tmp/cdv_photo_015.jpg
    ------WebKitFormBoundaryEzXidt71U741Mc45--
    

    Should this causing the problem? Since I can see I am sending the path but not the image itself..

    Before changing, I was using a custom directive, and was using $scope.files to append to my request in the upload function:

    <input type="file" file-input="files" multiple  onchange="angular.element(this).scope().filesChanged(this);upload();">
    <button ng-click="upload()">Upload</button>
    
  • Claudiu S
    Claudiu S over 9 years
    That's what you need to have when deadling with Angular.js requests.
  • Admin
    Admin over 9 years
    "TypeError: Cannot read property 'DATA_URL' of undefined" also you have one error in options. Please, fix it or you will get downgraded.