在使用javascript toDataURL保存HTML5画布时,如何插入PNG注释块?
我有一个压缩的canvas-to-png下载保护程序功能(见下面的代码)。 这段代码运行得很好,我对它的输出很满意。。。大部分。 第二次替换就足够了吗?那会是什么样子? 我唯一的其他选择是使用imagemagick对文件进行后期处理。 有什么想法吗 更完整地说:我想从javascript添加元数据。 我找到了这个链接 详细说明了结构,我可能有足够的时间弄清楚。 如果有人有经验,可以缩短这对我来说,我将不胜感激在使用javascript toDataURL保存HTML5画布时,如何插入PNG注释块?,javascript,html5-canvas,png,Javascript,Html5 Canvas,Png,我有一个压缩的canvas-to-png下载保护程序功能(见下面的代码)。 这段代码运行得很好,我对它的输出很满意。。。大部分。 第二次替换就足够了吗?那会是什么样子? 我唯一的其他选择是使用imagemagick对文件进行后期处理。 有什么想法吗 更完整地说:我想从javascript添加元数据。 我找到了这个链接 详细说明了结构,我可能有足够的时间弄清楚。 如果有人有经验,可以缩短这对我来说,我将不胜感激 //---------------------------------
//------------------------------------------------------------------
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');
}
Base-64表示与内部块几乎没有关系。它只是编码为字符串的[任何]二进制数据,因此可以通过纯字符串协议传输(或在文本上下文中显示) 创建一个示例可能有点宽泛,但希望展示主要步骤将有助于实现您的目标:
- 要将块添加到PNG,首先必须使用XHR/将其数据转换为PNG格式(对于数据URI,或者对于PNG格式(我建议使用)。请参阅)
- 向ArrayBuffer添加一个
- 转到数组中表示IHDR块开始的位置0x08,读取块的长度()(对于几乎所有PNG,它很可能具有相同的静态大小,但因为可能会有更改,并且您不需要记住块的大小,我们将从这里读取它)。将长度添加到位置(+4表示块末尾的CRC-32,如果在读取长度时未移动指针,则添加+4),通常这将使您到达位置0x21
- 您现在有了下一个块的位置,我们可以使用它插入我们自己的文本块
- 使用带有原始ArrayBuffer的子数组将第一个零件拆分为零件数组(常规数组),例如
new Uint8Array(ArrayBuffer,0,位置)代码>-您也可以使用该方法
- 将新块*生成为类型化数组并添加到部分数组
- 将原始PNG数组中没有第一部分的剩余部分添加到零件数组中,例如
new Uint8Array(arraybuffer,position,length-position)代码>
- 将零件数组直接用作参数(
;)将零件数组转换为Blob。这将包含自定义块。从那里,您可以使用对象URL将其作为图像读回(或使其可供下载)var newPng=newblob(零件数组,{type:“image/png”})
- 对于
请注意,它仅限于拉丁字符集,这意味着您必须粉刷要使用的字符串-对于unicode(UTF-8)内容使用tEXt
-为了简单起见,我们将在此处使用iTXt
tEXt
- 关键字和值在
块中由NUL字节(0x00)分隔,关键字必须按照中的定义准确键入文本
- 以这种方式构建区块:
- 从字符串获取字节大小
- 添加12个字节(用于长度、四个cc和crc-32)
- 以这种方式格式化数组(您也可以在此处使用数据视图):
Uint32-块的长度(数据仅以字节数表示) Uint32-“文本”为四个cc […]-数据本身(按字节复制) Uint32-CRC32*包括四个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
}
函数makeFourCC(n){//n=“tEXt”等,大端
var c=n.charCodeAt.bind(n);
return(c(0)&0x7f)Base-64表示与内部块没有什么关系。它只是编码为字符串的[任何]二进制数据,因此可以通过纯字符串协议传输(或在文本上下文中显示) 创建一个示例可能有点宽泛,但希望展示主要步骤将有助于实现您的目标:
- 要将块添加到PNG,首先必须使用XHR/将其数据转换为PNG格式(对于数据URI,或者对于PNG格式(我建议使用)。请参阅)
- 向ArrayBuffer添加一个
- 转到数组中表示IHDR区块开始的位置0x08,读取区块的长度()(对于几乎所有PNG,它很可能具有相同的静态大小,但因为可能会有更改,并且您不需要记住区块大小,我们将从这里读取)。将长度添加到位置(+4表示块末尾的CRC-32,如果在读取长度时未移动指针,则为+4),通常这会使您到达位置0x21
- 您现在有了下一个块的位置,我们可以使用它插入我们自己的文本块
- 使用带有原始ArrayBuffer的子数组将第一个零件拆分为零件数组(常规数组),例如,
-您也可以使用该方法new Uint8Array(ArrayBuffer,0,position);
- 将新块*生成为类型化数组并添加到部分数组
- 将原始PNG数组的剩余部分(不包括第一部分)添加到零件数组中,例如
new Uint8Array(arraybuffer,position,length-position);
- 将零件数组直接用作参数(
;)将零件数组转换为Blob。这将包含自定义块。从那里,您可以使用对象URL将其作为图像读回(或使其可供下载)var newPng=new Blob(零件数组,{type:“image/png”})
- 对于
请注意,它仅限于拉丁字符集,这意味着您必须粉刷要使用的字符串-对于unicode(UTF-8)内容使用tEXt
-为了简单起见,我们将在此处使用iTXt
tEXt
- 关键字和值由
文本块中的NUL字节(0x00)和关键字m分隔