In this tutorial, the author uses the FileURI
to copy the image from the temporary location to the device location, and finally returning the nativeURL
of this copied file.
window.resolveLocalFileSystemURL(fileURI, success, fail);
Instead of the FileURI
I have a base64 string (imageData) which I want to save also on the device location and return the nativeURL
of this saved image.
Is this possible and how would one achieve this with ngCordova?
1. draw on canvas in controller
$scope.drawAndSave = function() {
$scope.targetImages = [{nativeURL: "img/newyork.jpg"}, {nativeURL: "img/newyork.jpg"}]
drawCanvas().then(function(data){
$scope.outputImages = data; // works fine, can save it
for (var i = 0; i < data.length; i++) {
FileFactory.saveCanvasToDataUrl(data[i])
}
});
function drawCanvas() {
var pResults = $scope.targetImages.map(function (imageObj) {
return drawToCanvas(imageObj.nativeURL);
});
return $q.all(pResults);
}
function drawToCanvas(nativeURL) {
return $q(function (resolve) {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var img = new Image();
img.src = nativeURL;
img.onload = function () {
ctx.drawImage(img, 0, 0);
resolve(canvas.toDataURL("image/jpeg"));
};
});
} // draw to canvas
}
2. save canvas as image with for the input fileURI
the canvas.toDataUrl()
dataURI
.
.factory('FileFactory', function($cordovaFile, $q) {
var saveCanvasToDataUrl = function(imageData) {
copyFileURI(imageData)
}
// // http://devdactic.com/how-to-capture-and-store-images-with-ionic/
// todo: get file uri and copy it
var copyFileURI = function(fileURI) {
window.alert("saving ")
var q = $q.defer();
onImageSuccess(fileURI);
function onImageSuccess(fileURI) {
createFileEntry(fileURI);
}
function createFileEntry(fileURI) {
window.resolveLocalFileSystemURL(fileURI, copyFile, fail);
}
function copyFile(fileEntry) {
var name = fileEntry.fullPath.substr(fileEntry.fullPath.lastIndexOf('/') + 1);
var newName = makeid() + name;
window.resolveLocalFileSystemURL(cordova.file.dataDirectory, function(fileSystem2) {
fileEntry.copyTo(
fileSystem2,
newName,
onCopySuccess,
fail
);
},
fail);
}
function onCopySuccess(entry) {
q.resolve(entry.nativeURL)
}
function fail(error) {
q.reject(error)
window.alert("fail: " + JSON.stringify(error))
}
function makeid() {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i=0; i < 5; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}
return q.promise;
} // copy file uri, return new native url
var removeFile = function(nativeURL) {
var name = nativeURL.substr(nativeURL.lastIndexOf('/') + 1);
window.alert("trying to delete nativeURL name: " + nativeURL)
window.alert("cordova file directory: " + cordova.file.dataDirectory)
window.alert('name: ' + name)
$cordovaFile.checkFile(cordova.file.dataDirectory, name)
.then(function (success) {
window.alert("file found " + success)
$cordovaFile.removeFile(cordova.file.dataDirectory, name)
.then(function (success) {
// success
window.alert("file deleted " + success)
}, function (error) {
// error
window.alert("file not deleted error " + error)
});
}, function (error) {
// error
window.alert("file not ound " + JSON.stringify(error))
});
}
return {
copyFileURI: copyFileURI,
removeFile: removeFile,
saveCanvasToDataUrl: saveCanvasToDataUrl
}
});
Try following code to save base64 string to file
// I assume your base64 string is stored in a variable 'imageData'
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
function gotFS(fileSystem) {
fileSystem.root.getFile("image.jpg", {create: true, exclusive: false}, gotFileEntry, fail);
}
function gotFileEntry(fileEntry) {
fileEntry.createWriter(gotFileWriter, fail);
}
function gotFileWriter(writer) {
console.log("Start creating image file");
writer.seek(0);
writer.write(imageData);
console.log("End creating image file. File created");
}
Grouping all the above into a function
function savefile(dataurl){
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,
function (fileSystem) {
fileSystem.root.getFile("image.jpg", {create: true, exclusive: false},
function (fileEntry) {
fileEntry.createWriter(function (writer) {
console.log("Start creating image file");
writer.seek(0);
writer.write(dataurl);
console.log("End creating image file. File created");
}, fail);
}, fail);
}, fail);
}
function fail(){
console.log("Error");
}
Now you can call the function by savefile(dataurl)
where dataurl
is the base64 string
Updated:
Above version didn't had the folder selection. In below function app_folder_name variable has to be replace to folder in device.
function savefile(dataurl){
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,
function (fileSystem) {
fileSystem.root.getDirectory( app_folder_name, {create:true, exclusive: false},
function(directory) {
directory.root.getFile("image.jpg", {create: true, exclusive: false},
function (fileEntry) {
fileEntry.createWriter(function (writer) {
console.log("Start creating image file");
writer.seek(0);
writer.write(dataurl);
console.log("End creating image file. File created");
}, fail);
}, fail);
}, fail);
}, fail);
}