1

我有以下代码将图像写入文件系统,并将其读回以进行显示。在尝试文件系统 API 之前,我将整个 base64 图像加载到 src 属性中,并且图像显示正常。问题是图像可能很大,所以如果添加几张 5MB 的图像,就会耗尽内存。所以我想我只是将它们写入 tmp 存储并且只将 URL 传递给 src 属性。麻烦的是,什么都没有显示。

最初我认为 URL 可能有问题,但后来我进入文件系统目录,找到它所指的图像并用真正的二进制图像物理替换它,并将其重命名为与替换图像相同。这工作正常,图像显示正确,所以 URL 看起来不错。

我能得出的唯一结论是图像的写入在某种程度上是错误的——尤其是在创建 blob 的位置。我查看了blob API,看不到任何我可能错过的东西,但是我显然做错了什么,因为它似乎对其他人有用。

顺便说一句,我还尝试将图像存储在 IndexedDB 中并使用 createObjectURL 来显示图像 - 同样,虽然 URL 看起来正确,但屏幕上没有显示任何内容。因此尝试文件系统 API。在这两种情况下,blob 创建是相同的,具有相同的数据。

正如我提到的,源数据是一个 base64 编码的字符串。是的,我也尝试将原始 base64 数据存储在 blob 中(带和不带前缀),但这也不起作用。

其他信息 - chrome 版本 28,在 linux Ubuntu 上


    //strip the base64 `enter code here`stuff ...
    var regex = /^data.+;base64,/;
    if (regex.test(imgobj)) {   //its base64
        imgobj = imgobj.replace(regex,"");
        //imgobj = B64.decode(imgobj);
        imgobj = window.atob(imgobj);
    } else {
        console.log("it's already :", typeof imgobj);
    }

    // store the object into the tmp space
    window.requestFileSystem(window.TEMPORARY, 10*1024*1024, function(fs) {
        // check if the file already exists
        fs.root.getFile(imagename, {create: false}, function(fileEntry) {
            console.log("File exists: ", fileEntry);
            callback(fileEntry.toURL(), fileEntry.name);
                        //
        }, function (e) {   //file doesn't exist
            fs.root.getFile(imagename, {create: true}, function (fe) {
                console.log("file is: ", fe);
                fe.createWriter(function(fw){
                    fw.onwriteend = function(e) {
                        console.log("write complete: ", e);
                        console.log("size of file: ", e.total)
                        callback(fe.toURL(), fe.name);
                    };
                    fw.onerror = function(e) {
                        console.log("Write failed: ", e.toString());
                    };
                    var data = new Blob([imgobj], {type: "image/png"});
                    fw.write(data);
                }, fsErrorHandler);
            }, fsErrorHandler);
        });
        // now create a file
    }, fsErrorHandler);

回调的输出是:

<img class="imgx" src="filesystem:file:///temporary/closed-padlock.png" width="270px" height="270px" id="img1" data-imgname="closed-padlock.png">

除非有人可以提供一些指导,否则我有点停滞不前...

更新

我运行了一个测试,使用 B64encoder/decoder 和 atob/btoa 对 base64 图像进行编码和解码 -

console.log(imgobj); // this is the original base64 file from the canvas.toDataURL function
/* B64 is broken*/
B64imgobjdecode = B64.decode(imgobj);
B64imgobjencode = B64.encode(B64imgobjdecode);
console.log(B64imgobjencode);
/* atob and btoa decodes and encodes correctly*/
atobimgobj = window.atob(imgobj);
btoaimgobj = window.btoa(atobimgobj);
console.log(btoaimgobj);

结果表明 btoa/atob 功能正常工作,但 B64 不能 - 可能是因为原始编码没有使用 B64.encode 功能......

在文件系统 TEMPORARY 中生成的文件,我通过在线 base64 编码器进行比较,结果完全不同。所以问题是 - 在文件系统临时存储中,图像应该是一个精确的图像,还是填充了只有文件系统 API 才能理解的“东西”?请记住,我将原始 PNG 放在文件系统目录中并且图像正确显示,这往往表明有关图像的元数据(例如文件名)保存在其他地方......

有这个工作实现的人可以确认图像是作为图像存储在文件系统中,还是填充了额外的元数据?

4

1 回答 1

2

因此,要回答我自己的问题——核心问题在于 base64 编码/解码——从那时起,我将其更改为使用 ajax 和 responseTypes 之类的东西,例如 arraybuffer 和 blob,并且事情已经开始工作了。为了回答问题的最后一部分,这就是我发现的——在文件系统 tmp 存储中,是的,该文件应该是一个精确的二进制副本——在 chrome 和 phonegap 中验证了这一点。

于 2013-07-31T05:28:36.867 回答