1

(A duplicate of my Ionic forum post, but may be better suited for SO.)

I have created an Ionic app which works as a complementary service to a Drupal 8 web portal. Portal users can log into the app with their web credentials, and their user information is synced across devices.

One of these pieces of information is their profile picture. I have it set up so that the user can select an image from their device's photo library to set as their profile picture on the app, and the app then converts the image to a blob and posts it to the web portal, which then updates it on the portal accordingly.

The code to execute this is as follows (adapted from https://stackoverflow.com/a/30896068/5306408):

$scope.getPhoto = function() {

    getPic = function(type) {

        function picSuccess(imageURI) {
            window.resolveLocalFileSystemURL(imageURI, function(finalURI) {
                savepic(finalURI.nativeURL);
            }, function(err) {
                console.log(err);
            });
        }

        navigator.camera.getPicture(picSuccess, picError, {quality: 10, targetWidth: 800, encodingType: 0, correctOrientation: true, destinationType: navigator.camera.DestinationType.FILE_URI, saveToPhotoAlbum: false, sourceType: type});
    }

    picError = function(e) { console.log(e);}

    var photo_popup = $ionicPopup.show({ 
        template: "Would you like to change your photo?",
        scope: $scope,
        title: "Photo",
        cssClass: "photo-popup",
        buttons: [
            {text: '<b>Choose from gallery</b>', onTap: function(e) { getPic(0); },
            {text: "Cancel"}
        ]
    });
};

function savepic(finalURI) {
    var name = finalURI.substr(finalURI.lastIndexOf('/') + 1);
    var namePath = finalURI.substr(0, finalURI.lastIndexOf('/') + 1);
    var newPath = cordova.file.dataDirectory + name;
    $cordovaFile.copyFile(namePath, name, cordova.file.dataDirectory, name).then(function(info) {
        function addFormData() {
            d = $q.defer();
            var getFileBlob = function (url, cb) {
                var xhr = new XMLHttpRequest();
                xhr.open("GET", url);
                xhr.responseType = "blob";
                xhr.addEventListener('load', function() {
                    cb(xhr.response);
                }); 
                xhr.send();
            };

            var blobToFile = function (blob, name) {
                blob.lastModifiedDate = new Date();
                blob.name = name;
                return blob;
            };

            var getFileObject = function(filePathOrUrl, cb) {
                getFileBlob(filePathOrUrl, function (blob) {
                    cb(blobToFile(blob, 'output.jpg'));
                }); 
            };

            getFileObject(newPath, function (fileObject) {
                var dat = new FormData();
                dat.append('file', fileObject);
                dat.append('text', JSON.stringify({"imagedate": Date.now()}));
                d.resolve(dat);
            });
            return d.promise;
        }

        addFormData().then(function(dataform) {
            $http({method: 'POST', url: 'connector for portal service goes here', data: dataform, headers: {'Authorization': (auth header defined elsewhere), 'Content-Type': undefined}, transformRequest: angular.identity}).then(function(result) {
                //database logic
            }, function(e) {
                console.log(e);
            });
        });
    }, function(err) { console.log(err); });
}

Functionally, this code works. The issue I am having is that images which are 1.3 MB on a device are sometimes resulting in post requests of over 8 megabytes. The server cannot accept post requests that large and the portal-side update fails.

I have seen topics like this one for PhoneGap which had the same problem, but the accepted solution is already integrated into my code and it persists. I am stumped. Does anyone know why this might be happening?

pidgezero
  • 153
  • 7
  • Does this happens on iOS? Android? Both? Might be possible that the blob conversion is the one causing the size increase? why don't you use cordova-plugin-file-transfer to upload the images instead? – jcesarmobile May 25 '17 at 14:37
  • It happens on iOS, for Android I use a different plugin (cordova imagepicker) and the problem does not seem to happen there. – pidgezero May 25 '17 at 14:41
  • I've been doing some tests and using file transfer plugin to upload, the size is not increased. Images from an iPod touch with 1936 × 2592 resolution are around 150KB. BTW, targetWidth doesn't work if you don't provide targetHeight. Setting both to 800 (it maintains aspect ratio) reduces the size to around 20KB. So the problem is not on the camera plugin. – jcesarmobile May 25 '17 at 18:11

1 Answers1

1

I have had the same problem. Changing the destinationType from FILE_URI to NATIVE_URI fixed the issue for me. The file size did not increased and the file name was also correct.