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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20419574/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 18:26:36  来源:igfitidea点击:

Saving dataURL(base64) to file on PhoneGap (android)

javascriptcanvasfile-iocordovabase64

提问by lukaszkups

I'm converting canvas to dataURL(base64) type and I wanted to save it to phone filesystem using PhoneGap's writer but without success (I get broken file which I cannot open) - here's some of my code:

我正在将画布转换为 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);
            }
        );

I've tried also other solution from stackoverflow, which was based on addtional java plugin but it hasn't work for me. Is there pure JS(with additional js libs) solution for it?

我也尝试过来自 stackoverflow 的其他解决方案,它基于附加的 Java 插件,但对我不起作用。是否有纯 JS(带有额外的 js 库)解决方案?

采纳答案by lukaszkups

You may need to request larger file quota for the file system that is big enough to hold the image. Default is typically 5 mb but may vary in the different browsers as it's not standarized.

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

If the length of the data-uri exceeds this (which is likely considering it's a PNG file with 33% added 33% overhead as base64) the file won't save properly.

如果数据 uri 的长度超过此长度(这可能考虑到它是一个 PNG 文件,其中 33% 添加了 33% 作为 base64 的开销),该文件将无法正确保存。

You can request quota using the quota API:

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

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

More details can be found here.

可以在此处找到更多详细信息。

回答by Druin

FileWriter's write method does not take a base64 string. According to the docs (http://docs.phonegap.com/en/edge/cordova_file_file.md.html#FileWriter) text will be encoded as UTF-8 before being written. So your base64 string is being encoded before writing to the file so it's not valid image data. You have to pass your image data as a Blob or an ArrayBuffer. Note this only works on iOS and Android. Have a look at Jeremy Banks' b64toBlob function in this answer: https://stackoverflow.com/a/16245768

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;
}

You can pass the resulting blob into the write method.

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

回答by Kristian Primdal

You also have to take into account that you are getting a base64 encoded picture, so you cannot just save the as an images file an expect it to be a image.

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

So you have to Base64 decode that first before it will be an image. Maybe look at atob to do that https://developer.mozilla.org/en-US/docs/Web/API/Window.atob

所以你必须先对它进行 Base64 解码,然后才能成为图像。也许看看 atob 来做到这一点 https://developer.mozilla.org/en-US/docs/Web/API/Window.atob