【发布时间】:2013-04-06 07:07:59
【问题描述】:
我正在尝试允许用户保存已渲染到画布的图像。可能有多个图像,我希望用户能够一次下载所有图像作为单个 tar 文件。我正在尝试编写代码来生成这个 tar 文件。我已经完成了大部分工作,但是当最后将 tar 文件下载到我的计算机时,我发现构成 png 文件的一些二进制数据已损坏。以下是相关代码:
var canvBuffer = $('<canvas>').attr('width', canvasWidth).attr('height', canvasHeight);
var ctxBuffer = canvBuffer[0].getContext('2d');
imgData.data.set(renderedFrames[0]);
ctxBuffer.putImageData(imgData,0,0);
var strURI = canvBuffer[0].toDataURL();
var byteString = atob(decodeURIComponent(strURI.substring(strURI.indexOf(',')+1)));
toTar([byteString]);
function toTar(files /* array of blobs to convert */){
var tar = '';
for (var i = 0, f = false, chkSumString, totalChkSum, out; i < files.length; i++) {
f = files[i];
chkSumString = '';
var content = f;
var name = 'p1.png'.padRight('\0', 100);
var mode = '0000664'.padRight('\0', 8);
var uid = (1000).toString(8).padLeft('0', 7).padRight('\0',8);
var gid = (1000).toString(8).padLeft('0', 7).padRight('\0',8);
var size = (f.length).toString(8).padLeft('0', 11).padRight('\0',12);
var mtime = '12123623701'.padRight('\0', 12); // modification time
var chksum = ' '; // enter all spaces to calculate chksum
var typeflag = '0';
var linkname = ''.padRight('\0',100);
var ustar = 'ustar \0';
var uname = 'chris'.padRight('\0', 32);
var gname = 'chris'.padRight('\0', 32);
// Construct header with spaces filling in for chksum value
chkSumString = (name + mode + uid + gid + size + mtime + chksum + typeflag + linkname + ustar + uname + gname).padRight('\0', 512);
// Calculate chksum for header
totalChkSum = 0;
for (var i = 0, ch; i < chkSumString.length; i++){
ch = chkSumString.charCodeAt(i);
totalChkSum += ch;
}
// reconstruct header plus content with chksum inserted
chksum = (totalChkSum).toString(8).padLeft('0', 6) + '\0 ';
out = (name + mode + uid + gid + size + mtime + chksum + typeflag + linkname + ustar + uname + gname).padRight('\0', 512);
out += content.padRight('\0', (512 + Math.floor(content.length/512) * 512)); // pad out to a multiple of 512
out += ''.padRight('\0', 1024); // two 512 blocks to terminate the file
tar += out;
}
var b = new Blob([tar], {'type': 'application/tar'});
window.location.href = window.URL.createObjectURL(b);
}
我将先前渲染的帧放在未渲染的画布上,并使用 canvases toDataURL() 方法对带有 Base64 编码的帧的编码 png 版本。接下来我使用 atob 将其转换为字节字符串,以便可以将其附加到我正在生成的 tar 文件的内容中。
当我在十六进制编辑器中查看文件时,我的 tar 标头是正确的,但 png 的内容并不完全正确。 ASCII 内容看起来正常,但二进制数据被打乱了。
我们将不胜感激提供的任何帮助。谢谢。
PS
我附上了我看过的相关帖子的链接。他们很有帮助,但我还没有看到任何可以完全解决我的问题的东西。谢谢。
Convert Data URI to File then append to FormData 和 Data URI to Object URL with createObjectURL in chrome/ff
【问题讨论】:
-
您是否尝试发送参数
image/png就像在stackoverflow.com/questions/923885/… 中一样 -
我没有,因为 png 应该是默认值,如上所述 window.location.href = dataURI;保存一个有效的 png 文件。只是要确定;但是,我只是尝试过。没有运气。谢谢。
-
您的意思是
canvas.toDataURL有错误并返回损坏的图像,还是您的意思?如果我正确理解代码,第一行设置画布元素的宽度和高度。完成后,画布将被擦除。 -
不,toDataURL 没有任何问题,可以正常工作。我只是将画布用作生成 png 压缩图像的便捷方式。问题是您收到 base64 编码字符串中的图像。通常,您会将此字符串设置为链接或 img 元素的 src,并由浏览器处理对其进行解码。就我而言;但是,我想在 JavaScript 中解码 base64 字符串。我需要它作为一个字节串来构建它并将它打包到一个 tar 文件中。
-
如果不使用
decodeURIComponent会怎样?
标签: javascript binary blob data-url