使用javascript toDataURL保存HTML5画布时,如何插入PNG注释块? [英] How do I insert a PNG comment block when saving an HTML5 canvas using javascript toDataURL?

查看:52
本文介绍了使用javascript toDataURL保存HTML5画布时,如何插入PNG注释块?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个紧凑的canvas-to-png下载保护程序功能(请参见下面的代码).这段代码效果很好,我对它的输出感到满意……大部分情况下.再更换一次就足够了吗?那会是什么样子呢?我唯一的其他选择是使用imagemagick对文件进行后处理.有什么想法吗?

I have a compact canvas-to-png download saver function (see code below). This code works very well and I am satisfied with its output... mostly. Would a second replace suffice? What would that replace look like? My only other option is to post-process the file with imagemagick. Any ideas?

更完全:我想从javascript中添加元数据.我发现此链接 http://dev.exiv2.org/projects/exiv2/wiki/The_Metadata_in_PNG_files 详细介绍了这些结构,我也许可以花足够的时间弄清楚.如果有人有经验并且可以为我缩短时间,我将不胜感激.

More completely: I want to add metadata from javascript. I found this link http://dev.exiv2.org/projects/exiv2/wiki/The_Metadata_in_PNG_files which details the structures, and I may be able to figure it out with sufficient time. If anyone has experience and can shorten this for me, I would appreciate it.

        //------------------------------------------------------------------
        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表示与内部块无关.只是编码为字符串的[任何]二进制数据,因此可以通过仅字符串协议传输(或在文本上下文中显示).

The Base-64 representation has little to do with the internal chunks. It's just [any] binary data encoded as string so it can be transferred over string-only protocols (or displayed in a textual context).

创建示例可能有点宽泛,但是希望展示主要步骤将有助于实现您想要的目标:

It's perhaps a bit broad to create an example, but hopefully showing the main steps will help to achieve what you're looking for:

  • 要向PNG添加块,您首先必须将其数据转换为 ArrayBuffer 对于数据URI,使用XHR/获取,或 FileReader ,以防您将PNG命名为 Blob (我建议.请参见 toBlob() ).
  • DataView 添加到ArrayBuffer
  • 转到表示IHDR块起始位置的数组中的位置0x08,读取块的长度( subarray 方法.
  • 将新chunk *作为类型化数组并添加到part-array
  • 将原始PNG数组的其余部分(不包括第一部分)添加到part数组中,例如 new Uint8Array(arraybuffer,position,length-position);
  • 直接使用零件数组作为参数将零件数组转换为Blob( var newPng = new Blob(partArray,{type:"image/png"});).现在,它将包含自定义块.从那里,您可以将Object-URL与它一起使用以将其读回为图像(或使其可供下载).
  • To add a chunk to a PNG you would first have to convert the data for it into an ArrayBuffer using XHR/fetch in the case of Data-URIs, or FileReader in case you have the PNG as Blob (which I recommend. See toBlob()).
  • Add a DataView to the ArrayBuffer
  • Go to position 0x08 in the array which will represent the start of the IHDR chunk, read the length of the chunk (Uint32) (it's very likely it has the same static size for almost any PNG but since it's possible to have changes, and you don't need to remember the chunk size we'll just read it from here). Add length to position (+4 for CRC-32 at the end of the chunk, and +4 if you didn't move the pointer while reading the length), typically this should land you at position 0x21.
  • You now have the position for the next chunk which we can use to insert our own text chunks
  • Split that first part into a part-array (a regular array) using a sub-array with the original ArrayBuffer, e.g. new Uint8Array(arraybuffer, 0, position); - you can also use the subarray method.
  • Produce the new chunk* as typed array and add to part-array
  • Add the remaining part of the original PNG array without the first part to the part-array, e.g. new Uint8Array(arraybuffer, position, length - position);
  • Convert the part-array to a Blob using the part-array directly as argument (var newPng = new Blob(partArray, {type: "image/png"});). This will now contain the custom chunk. From there you can use an Object-URL with it to read it back as an image (or make it available for download).

*)块:

  • 对于 tEXt ,请注意,它仅限于Latin-1字符集,这意味着您必须粉刷要使用的字符串-对 iTXt 使用unicode(UTF-8)内容-为简单起见,我们将在此处使用 tEXt .
  • 关键字和值在 tEXt 块中以NUL字节(0x00)分隔,并且关键字必须完全按照
查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆