ユーザーがキャンバスにレンダリングされた画像を保存できるようにしようとしています。複数のイメージが存在する可能性があり、ユーザーがすべてのイメージを 1 つの 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 バージョンに変換しています。次に、生成する tar ファイルの内容に追加できるように、atob を使用してこれをバイト文字列に変換します。
16 進エディタでファイルを表示すると、tar ヘッダーは正しいのですが、png の内容が正しくありません。ASCII の内容は正常に見えますが、バイナリ データはスクランブルされています。
提供されたヘルプは大歓迎です。ありがとう。
PS
私が見た関連記事へのリンクを添付しました。それらは役に立ちましたが、私の問題を完全に解決するものはまだ見たことがありません. ありがとう。
データ URI をファイルに変換してから FormDataに追加し、データ URI を chrome/ff の createObjectURL を使用してオブジェクト URL に追加します。