Ce n'est pas exactement le scénario du PO mais une réponse à ceux de certains des commentateurs. C'est une solution basée sur Cordova et Angular 1, qui devrait être adaptable à d'autres frameworks comme jQuery. Il vous donne un Blob à partir de données Base64 que vous pouvez stocker quelque part et le référencer à partir de javascript / html côté client.
Il répond également à la question initiale sur la façon d'obtenir une image (fichier) à partir des données Base 64:
La partie importante est la Base 64 - Conversion binaire:
function base64toBlob(base64Data, contentType) {
contentType = contentType || '';
var sliceSize = 1024;
var byteCharacters = atob(base64Data);
var bytesLength = byteCharacters.length;
var slicesCount = Math.ceil(bytesLength / sliceSize);
var byteArrays = new Array(slicesCount);
for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
var begin = sliceIndex * sliceSize;
var end = Math.min(begin + sliceSize, bytesLength);
var bytes = new Array(end - begin);
for (var offset = begin, i = 0; offset < end; ++i, ++offset) {
bytes[i] = byteCharacters[offset].charCodeAt(0);
}
byteArrays[sliceIndex] = new Uint8Array(bytes);
}
return new Blob(byteArrays, { type: contentType });
}
Le découpage est nécessaire pour éviter les erreurs de mémoire insuffisante.
Fonctionne avec les fichiers jpg et pdf (du moins c'est ce que j'ai testé). Devrait également fonctionner avec d'autres types MIME / contenttypes. Vérifiez les navigateurs et leurs versions que vous visez, ils doivent prendre en charge Uint8Array, Blob et atob.
Voici le code pour écrire le fichier sur le stockage local de l'appareil avec Cordova / Android:
...
window.resolveLocalFileSystemURL(cordova.file.externalDataDirectory, function(dirEntry) {
var filename = attachment.id + "-" + (attachment.fileName ? attachment.fileName : 'image') + "." + (attachment.fileType ? attachment.fileType : "jpg");
dirEntry.getFile(filename, { create: true, exclusive: false }, function(fileEntry) {
var binary = base64toBlob(attachment.document, attachment.mimetype);
writeFile(fileEntry, binary).then(function() {
attachment.document = fileEntry.nativeURL;
}, function(error) {
WL.Logger.error("Error writing local file: " + error);
reject(error.code);
});
}, function(errorCreateFile) {
WL.Logger.error("Error creating local file: " + JSON.stringify(errorCreateFile));
reject(errorCreateFile.code);
});
}, function(errorCreateFS) {
WL.Logger.error("Error getting filesystem: " + errorCreateFS);
reject(errorCreateFS.code);
});
...
Écriture du fichier lui-même:
function writeFile(fileEntry, dataObj) {
return $q(function(resolve, reject) {
fileEntry.createWriter(function(fileWriter) {
fileWriter.onwriteend = function() {
WL.Logger.debug(LOG_PREFIX + "Successful file write...");
resolve();
};
fileWriter.onerror = function(e) {
WL.Logger.error(LOG_PREFIX + "Failed file write: " + e.toString());
reject(e);
};
if (!dataObj) {
dataObj = new Blob(['missing data'], { type: 'text/plain' });
}
fileWriter.write(dataObj);
});
})
}
J'utilise les dernières versions de Cordova (6.5.0) et Plugins:
J'espère que cela mettra tout le monde ici dans la bonne direction.