File.writeFile()
создает PNG-файл 0 байт при попытке написать Blob, сделанный из base64 данные.
В моем приложении я пытаюсь создать файл, состоящий из данных base64, хранящихся в db. Полученный эквивалент данных представляет собой небольшую кривую сглаживания графа черного цвета на прозрачном фоне (не более 300 х 320 пикселей), который ранее был создан и сохранен из элемента холста. Я самостоятельно проверил, что сохраненные данные base64 действительно правильны, предоставляя его на одном из различных кодеров/декодеров base64, доступных в Интернете.
Выход из "Ионные Info"
--------------------------------
Your system information:
Cordova CLI: 6.3.1
Gulp version: CLI version 3.9.1
Gulp local:
Ionic Framework Version: 2.0.0-rc.2
Ionic CLI Version: 2.1.1
Ionic App Lib Version: 2.1.1
Ionic App Scripts Version: 0.0.39
OS:
Node Version: v6.7.0
--------------------------------
Платформа разработки является ОС Windows 10, и я тестировал непосредственно на Samsung Galaxy S4 S7 и до сих пор.
Я знаю, что данные base64 необходимо преобразовать в двоичные данные (как Blob), так как файл еще не поддерживает запись base64 непосредственно в файл изображения. Я нашел различные методы, чтобы сделать это, и код, который, как мне кажется, больше всего (и отражает аналогичный способ, который я сделал бы это в java, показан ниже):
Основной код от конструктора:
this.platform.ready().then(() => {
this.graphDataService.getDataItem(this.job.id).then((data) =>{
console.log("getpic:");
let imgWithMeta = data.split(",")
// base64 data
let imgData = imgWithMeta[1].trim();
// content type
let imgType = imgWithMeta[0].trim().split(";")[0].split(":")[1];
console.log("imgData:",imgData);
console.log("imgMeta:",imgType);
console.log("aftergetpic:");
// this.fs is correctly set to cordova.file.externalDataDirectory
let folderpath = this.fs;
let filename = "dotd_test.png";
File.resolveLocalFilesystemUrl(this.fs).then((dirEntry) => {
console.log("resolved dir with:", dirEntry);
this.savebase64AsImageFile(dirEntry.nativeURL,filename,imgData,imgType);
});
});
});
Helper конвертировать base64 в Blob:
// convert base64 to Blob
b64toBlob(b64Data, contentType, sliceSize) {
//console.log("data packet:",b64Data);
//console.log("content type:",contentType);
//console.log("slice size:",sliceSize);
let byteCharacters = atob(b64Data);
let byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
let slice = byteCharacters.slice(offset, offset + sliceSize);
let byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
let byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
console.log("size of bytearray before blobbing:", byteArrays.length);
console.log("blob content type:", contentType);
let blob = new Blob(byteArrays, {type: contentType});
// alternative way WITHOUT chunking the base64 data
// let blob = new Blob([atob(b64Data)], {type: contentType});
return blob;
}
сохранить изображение с File.writeFile()
// save the image with File.writeFile()
savebase64AsImageFile(folderpath,filename,content,contentType){
// Convert the base64 string in a Blob
let data:Blob = this.b64toBlob(content,contentType,512);
console.log("file location attempt is:",folderpath + filename);
File.writeFile(
folderpath,
filename,
data,
{replace: true}
).then(
_ => console.log("write complete")
).catch(
err => console.log("file create failed:",err);
);
}
Я пробовал десятки различных методов декодирования, но эффект тот же. Однако, если я жёстко простые текстовые данные в разделе writeFile()
, например так:
File.writeFile(
folderpath,
"test.txt",
"the quick brown fox jumps over the lazy dog",
{replace: true}
)
текстовый файл создан правильно в ожидаемом месте с текстовой строкой выше в нем.
Тем не менее, я заметил, что файл PNG или файл рабочего текста выше, в обоих случаях в предложении «.then()» из обещания файла никогда не срабатывает.
Кроме того, я сменил вышеупомянутый метод и использовал Ионные 2 нативный Base64-To-галереи библиотеки для создания изображений, которые работали без проблем. Тем не менее, наличие изображений в галерее фотографий пользователя или в рулоне камеры не является для меня вариантом, так как я не хочу рисковать собственными фотографиями пользователя при сортировке/упаковке/передаче/удалении изображений, обработанных данными. Изображения должны быть созданы и управляться как часть приложения.
Пользователь marcus-robinson, похоже, столкнулся с аналогичной проблемой, описанной здесь, но это было по всем типам файлов, а не только двоичным типам, как представляется, здесь. Кроме того, этот вопрос, кажется, был закрыт:
https://github.com/driftyco/ionic/issues/5638
Любой испытывает что-то подобное, или, возможно, обнаружить некоторые ошибки, я мог бы вызвать? Я пробовал десятки альтернатив, но никто, похоже, не работает.