我有一个紧凑的canvas-to-png下载保护程序功能(参见下面的代码)。 这段代码工作得非常好,我对它的输出很满意......主要是。 第二次更换是否足够?那替换会是什么样的? 我唯一的另一种选择是使用imagemagick对文件进行后处理。 有什么想法吗?
更完整:我想从javascript添加元数据。 我找到了这个链接http://dev.exiv2.org/projects/exiv2/wiki/The_Metadata_in_PNG_files 详细介绍了结构,我可以用足够的时间来弄清楚它。 如果有人有经验并可以为我缩短这一点,我将不胜感激。
//------------------------------------------------------------------
function save () // has to be function not var for onclick to work.
//------------------------------------------------------------------
{
var element = document.getElementById("saver");
element.download = savename;
element.href = document.
getElementById(id.figure1a.canvas).
toDataURL("image/png").
replace(/^data:image\/[^;]/,'data:application/octet-stream');
}
答案 0 :(得分:1)
Base-64表示与内部块几乎没有关系。它只是[任何]二进制数据编码为字符串,因此它可以通过字符串协议传输(或在文本上下文中显示)。
创建一个示例可能有点宽泛,但希望显示主要步骤将有助于实现您的目标:
toBlob()
(我建议使用。请参阅DataView)。new Uint8Array(arraybuffer, 0, position);
- 您还可以使用spec方法。new Uint8Array(arraybuffer, position, length - position);
var newPng = new Blob(partArray, {type: "image/png"})
;)。这将包含自定义块。从那里你可以使用Object-URL将其作为图像读回(或使其可供下载)。*)Chunk:
tEXt
,请注意它仅限于Latin-1字符集,这意味着您必须粉饰您要使用的字符串 - 使用iTXt
作为unicode(UTF-8)内容 - 为简单起见,我们在这里使用tEXt
。tEXt
块中的NUL字节(0x00)分隔,关键字必须按照this part中的定义进行输入。
Uint32 - length of chunk (data only in number of bytes)
Uint32 - "tEXt" as four-cc
[...] - The data itself (copy byte-wise)
Uint32 - CRC32* which includes the FourCC but not length and itself.
PNG中的所有数据都是大端的。
要计算CRC-32,请随意使用我的pngtoy解决方案的this way(构建LUT https://github.com/bvaughn/react-virtualized/blob/master/docs/Grid.md#cellrangerenderer)。以下是格式化四个cc的一种方法:
function makeFourCC(n) { // n = "tEXt" etc., big-endian
var c = n.charCodeAt.bind(n);
return (c(0) & 0x7f) << 24 | (c(1) & 0x7f) << 16 | (c(2) & 0x7f) << 8 | c(3) & 0x7f
}