将dataURL(base64)保存到PhoneGap上的文件(android)

时间:2013-12-06 08:44:59

标签: javascript canvas file-io cordova base64

我正在将canvas转换为dataURL(base64)类型,我想使用PhoneGap的编写器将其保存到手机文件系统但没有成功(我得到了无法打开的文件) - 这是我的一些代码:

        var dataURL = document.getElementById("gen").toDataURL('image/png'); //substr() .replace('datadata:image/png;base64,', '');

         window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
         function gotFS(fileSystem) {
            fileSystem.root.getFile("screenshot.png", {create: true, exclusive: false}, gotFileEntry, fail);
        }

        function gotFileEntry(fileEntry) {
            fileEntry.createWriter(gotFileWriter, fail);
        }

        function gotFileWriter(writer) {
            console.log("open and write");
            writer.seek(0);
            writer.write(dataURL);
            console.log("close and save");
        }

        function fail(error) {
            console.log(error.code);
        }

        var fileTransfer = new FileTransfer();
        fileTransfer.download("/", screenshot.png,  
            function(entry) {
                alert("download complete");
            },
            function(error) {
                alert("download error source " + error.source);
                alert("download error target " + error.target);
                alert("upload error code" + error.code);
            }
        );

我也尝试过stackoverflow的其他解决方案,它基于addtional java插件,但它对我不起作用。是否有纯JS(附加js libs)解决方案?

3 个答案:

答案 0 :(得分:6)

FileWriter的write方法不带base64字符串。 根据文档(http://docs.phonegap.com/en/edge/cordova_file_file.md.html#FileWriter) 在写入之前,文本将被编码为UTF-8。因此,在写入文件之前,您的base64字符串正在被编码,因此它不是有效的图像数据。 您必须将图像数据作为Blob或ArrayBuffer传递。请注意,这仅适用于iOS和Android。 在这个答案中看看Jeremy Banks的b64toBlob函数:https://stackoverflow.com/a/16245768

function b64toBlob(b64Data, contentType, sliceSize) {
    contentType = contentType || '';
    sliceSize = sliceSize || 512;

    var byteCharacters = atob(b64Data);
    var byteArrays = [];

    for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
        var slice = byteCharacters.slice(offset, offset + sliceSize);

        var byteNumbers = new Array(slice.length);
        for (var i = 0; i < slice.length; i++) {
            byteNumbers[i] = slice.charCodeAt(i);
        }

        var byteArray = new Uint8Array(byteNumbers);

        byteArrays.push(byteArray);
    }

    var blob = new Blob(byteArrays, {type: contentType});
    return blob;
}

您可以将生成的blob传递给write方法。

答案 1 :(得分:1)

您可能需要为文件系统请求更大的文件配额,该文件系统足以容纳图像。默认值通常为5 MB,但在不同的浏览器中可能会有所不同,因为它没有标准化。

如果data-uri的长度超过这个(这可能是因为它有一个PNG文件,其中33%的开销增加了33%作为base64),文件将无法正常保存。

您可以使用配额API请求配额:

webkitStorageInfo.requestQuota( 
    webkitStorageInfo.PERSISTENT
    newQuotaInBytes,
    quotaCallback,
    errorCallback);

可以找到更多详细信息here

答案 2 :(得分:1)

您还必须考虑到您正在获取base64编码的图片,因此您不能将其保存为图像文件,期望它成为图像。

所以你必须在它成为图像之前首先进行Base64解码。也许看看atob做那件事 https://developer.mozilla.org/en-US/docs/Web/API/Window.atob