如何节约使用javascript toDataURL的HTML5画布当我插入一个PNG注释块?(Ho

2019-10-31 05:36发布

我有一个紧凑的帆布至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');
        }

Answer 1:

基64表示有一点做与内部块。 它只是[任何]的二进制数据编码为字符串,以便它可以通过仅串的协议被传送(或在文本上下文显示)。

这或许有点广泛创建一个例子,但我希望展示的主要步骤将有助于实现您要查找的内容:

  • 要将块添加到PNG,你首先必须将数据转换为它变成一个ArrayBuffer通过XHR / 读取的数据的URI,或情况下的FileReader的情况下,你有PNG作为斑点 (我建议见toBlob() )。
  • a添加数据视图的ArrayBuffer
  • 走这将代表IHDR块的开始,读取块的长度(数组中的定位0x08的UINT32 )(这是很可能具有相同的静态大小几乎任何PNG但因为它是可能有变化,你不需要记住块大小我们就从这里阅读)。 添加长度位置(+4 CRC-32在块的结束,和+4如果你在阅读的长度没有移动指针),通常这应该在位置为0x21土地你。
  • 你现在有下一块,我们可以用它来插入我们自己的文本块中的位置
  • 拆分第一部分成使用子阵列与原始ArrayBuffer一部分阵列(规则阵列),例如new Uint8Array(arraybuffer, 0, position); -您也可以使用子阵方法。
  • 产生新的块*为类型数组,并添加至部件阵列
  • 添加原PNG阵列的剩余部分没有第一部分到部分阵列,例如new Uint8Array(arraybuffer, position, length - position);
  • 所述部分数组转换成直接使用部分阵列作为参数(一个斑点var newPng = new Blob(partArray, {type: "image/png"}) 现在,这将包含自定义块。 从那里,你可以使用一个对象的URL与它读回的图像(或使其可用于下载)。

*)组块:

  • 对于tEXt意识到这一点仅限于拉丁字母字符集,这意味着你将不得不粉饰你要使用的字符串-使用iTXt对于Unicode(UTF-8)的内容-我们将用tEXt在这里为简便起见。
  • 的关键字和值是通过在一个NUL字节(0×00)中分离tEXt块,并且关键字必须如在定义的原样键入规范 。
  • 构建块是这样的:
    • 得到的字符串的字节大小
    • 添加12个字节(长度,四CC和CRC-32)
    • 格式化阵列这种方式(你可以在这里使用一个数据视图以及):
      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溶液(LUT中建立这种方式 )。 下面是格式化四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
}


文章来源: How do I insert a PNG comment block when saving an HTML5 canvas using javascript toDataURL?