I am using the image-picker (cordova-imagePicker) plugin in order to get images from gallery and upload them to a server.
I am using Cordova 6.1.1 with Android platform 5.1.1 and the following plugins:
cordova-plugin-camera 2.2.0 "Camera"
cordova-plugin-compat 1.0.0 "Compat"
cordova-plugin-device 1.0.1 "Device"
cordova-plugin-file 4.2.0 "File"
cordova-plugin-imagepicker 1.1.0 "ImagePicker"
cordova-plugin-inappbrowser 1.4.0 "InAppBrowser"
cordova-plugin-media 2.3.0 "Media"
As callback to the plugin, I am converting the path I get to a File using the following code. Note that I use resolveFile
because this code is running also in desktop in which case, the entry is already a File object.
var resolveFile = function(entry) {
if (typeof(entry) === "string") {
var deferred = $q.defer();
// first convert to local file system URL
window.resolveLocalFileSystemURL(entry, function(fileEntry) {
// now read/convert the file to file object.
fileEntry.file(function(file) {
console.log("File converted to file entry");
deferred.resolve(file);
}, function(err) {
console.log("Failed to convert to file entry", err);
deferred.reject(err);
});
}, function(err) {
console.log("Failed to resolve to file URL", err);
deferred.reject(err);
});
return deferred.promise;
} else {
return $q.when(entry);
}
};
This, in turn is used to read the image and pass it to a function that uploads it to the server ($files
is what I am getting from plugin or from input in case of desktop/browser):
var upload = function () {
if (!$files[currentFile]) {
onAllFinished();
return;
}
file = $files[currentFile];
beforeLoad(file);
fileReader = new FileReader();
fileReader.onload = onload;
fileReader.onprogress = progress;
resolveFile(file).then(function(actualFile) {
fileReader.readAsDataURL(actualFile);
});
currentFile++;
};
In the above, onload cuts the image data (following 'base64,' in string) and sends it to the the upload code which expects a base64 string and uploads the data to the server using simple AJAX call:
var uploadPhoto = function(url, photo, callback, error)
$http.post(url, {
photo: photo,
})
.success(callback)
.error(function (data, status, headers, config) {
if (error)
error(data, status, headers, config);
});
The last function works also with the camera plugin camera plugin using DATA_URI
target (I know, it's not recommended) which also return a base64 string (so I can reuse the code).
It seems to me there's something wrong going on with the file reader output (I am guessing). What (I think) hints to that is that small images (10s kb) are loaded fine as well as already prepared base64 string from camera plugin but larger images (few MBs) that goes through the filereader (on Android, on desktop it is fine) are uploaded corrupted (see below).
Has anyone run into such issues? Can anyone suggest a fix (other than changing the code to use FileTransfer plugin)?
The original image:
The uploaded (corrupted) image. Note, some of it is read/uploaded fine:
See Question&Answers more detail:
os