在PhoneGap(安卓)中保存数据URL(base64)到文件

5

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

        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上的其他解决方案,这些方案基于添加额外的Java插件,但对我没有起作用。是否有纯JavaScript(带有额外的JavaScript库)的解决方案?


为什么要使用fileTransfer.download?使用writer.write(dataURL)保存图像不就足够了吗? - Michael
3个回答

7

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://dev59.com/UGQo5IYBdhLWcg3wMs-2#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
你可能需要为文件系统请求更大的文件配额,以便容纳图像。默认值通常为5MB,但由于其未经标准化,在不同的浏览器中可能会有所不同。
如果数据URI的长度超过了此限制(考虑到它是一个带有33%Base64开销的PNG文件,这很可能发生),则文件将无法正确保存。
您可以使用配额API请求配额:
webkitStorageInfo.requestQuota( 
    webkitStorageInfo.PERSISTENT
    newQuotaInBytes,
    quotaCallback,
    errorCallback);

更多细节可以在这里找到。

1
你还需要考虑到你得到的是经过base64编码的图片,因此你不能仅仅保存它作为图像文件并期望它成为一张图片。
因此,在它成为图像之前,你必须首先对其进行Base64解码。也许可以查看atob来完成这个任务 https://developer.mozilla.org/en-US/docs/Web/API/Window.atob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接