admin管理员组文章数量:1431720
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-pat 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 remended) 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:
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-pat 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 remended) 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:
Share Improve this question asked May 23, 2016 at 13:27 Tomer CaganTomer Cagan 1,18819 silver badges33 bronze badges1 Answer
Reset to default 9I found your question while searching for a solution for a similar problem. DataURL's of large images from camera would show up when used as the source of an image but the same image got corrupted when I use fileReader.readAsDataURL.
I've been able to bypass the problem by using fileReader.readAsBinaryData instead of fileReader.readAsDataURL and then turning the binarystring into a dataURL.
window.resolveLocalFileSystemURL(imageUri, function done(fileEntry) {
fileEntry.file(function (fileObj) {
var image = new Image();
var reader = new FileReader();
reader.onloadend = function (e) {
image.src = "data:image/jpeg;base64," + window.btoa(e.target.result)
}
reader.readAsBinaryString(fileObj);
}
}
Hopefully this helps you to find a workaround of your own.
本文标签: javascriptCordovaReading Large Image corrupts imageStack Overflow
版权声明:本文标题:javascript - Cordova - Reading Large Image corrupts image - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745583895a2664779.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论