2016-11-16 2 views
2

РезюмируяИонные 2/Cordova-плагин-файл File.writeFile() отказывается создать двоичный файл правильно (изображение PNG)

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

Любой испытывает что-то подобное, или, возможно, обнаружить некоторые ошибки, я мог бы вызвать? Я пробовал десятки альтернатив, но никто, похоже, не работает.

ответ

0

я получил, что работать с большинством кода:

this.file.writeFile(this.file.cacheDirectory, "currentCached.jpeg", this.b64toBlob(src, "image/jpg", 512) ,{replace: true}) 

Единственная разница у меня было:

let byteCharacters = atob(b64Data.replace(/^data:image\/(png|jpeg|jpg);base64,/, '')); 

вместо вашей

let byteCharacters = atob(b64Data); 

Примечание: Я не сделал используйте другие обрезки и т. д., как те методы, которые вы использовали в своем классе конструктора.

 Смежные вопросы

  • Нет связанных вопросов^_^