2016-11-16 28 views
2

总之离子2 /科尔多瓦-插件文件File.writeFile()拒绝正确地创建二进制文件(PNG图像)

File.writeFile()尝试写入从制成的斑点时创建的0字节的PNG文件base64数据。

在我的应用程序中,我试图创建一个由存储在数据库中的base64数据组成的文件。渲染的等效数据是在透明背景(从未多于300 x 320像素)上以黑色显示的小反锯齿图形曲线,此曲线先前已从画布元素创建并存储。我已经独立地验证了存储的base64数据通过在线提供的各种base64编码器/解码器之一来确实是正确的。从“离子信息”

-------------------------------- 
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,我已经直接在三星Galaxy S7和S4到目前为止测试。

我知道base64数据必须先转换为二进制数据(作为Blob),因为File还不支持将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); 
     }); 
     }); 

    }); 

助手为base64转换成团块:

// 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} 
    ) 

文件在预期的位置文本字符串上面它正确创建的文本。

但是,我注意到无论文件是0字节的PNG还是上面的工作文本文件,在两种情况下,文件承诺的“.then()”结果子句都不会触发。

此外,我换上面的方法和所使用的离子2天然的Base64到廊库来创建这没有问题工作的图像,。但是,在用户的图片库或相机胶卷中放置图像不是我的选择,因为我不希望在编组/打包/传输/删除数据渲染图像时冒着用户自己的照片风险。图像应该作为应用程序的一部分来创建和管理。

用户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); 

注:我没有使用其他修剪等,就像您在构造函数类中使用的技巧。

相关问题