将PNG图像joinAPNGanimation图像

是否有可能以某种方式使用nodejs将PNG图像join到APNGanimation图像中?

我只findPHP库: 链接

目前 ,不,它看起来不像。 维基百科列出了可用的软件 ,正如你所看到的,它不支持ImageMagick,它有一个节点封装器。 然而,你可能会发现你可以下载命令行工具apngasm和shell,如果你觉得值得一提的话,有一些Node命令行包装器可以使用child_processhttp://nodejs.org/ api / child_process.html )。

我不知道nodejs,但你可以尝试APNGcanvas 。 APNG使用HTML5(-webkit-canvas),JavaScript(jQuery)。

“APNG-canvas是一个库,用于在支持canvas的浏览器(Google Chrome,Internet Explorer 9,Apple Safari)中显示animationPNG文件。”

工作演示在这里。

没有这个库,但实现起来很简单。 在Wikipedia中描述了将多个PNG文件合并到单个APNG中的algorithm:

  1. 把第一个PNG文件的所有块作为构build基础。
  2. 在图像标题块(IHDR)之后插入一个animation控制块(acTL)。
  3. 如果第一个PNG要成为animation的一部分,则在图像数据块(IDAT)之前插入一个帧控制块(fcTL)。
  4. 对于其余每个帧,添加一个帧控制块(fcTL)和一个帧数据块(fdAT)。 然后添加图像结束块(IEND)。 帧数据块(fdAT)的内容是从其各个源图像的图像数据块(IDAT)中获取的。

这是一个示例实现:

 const fs = require('fs') const crc32 = require('crc').crc32 function findChunk(buffer, type) { let offset = 8 while (offset < buffer.length) { let chunkLength = buffer.readUInt32BE(offset) let chunkType = buffer.slice(offset + 4, offset + 8).toString('ascii') if (chunkType === type) { return buffer.slice(offset, offset + chunkLength + 12) } offset += 4 + 4 + chunkLength + 4 } throw new Error(`Chunk "${type}" not found`) } const images = process.argv.slice(2).map(path => fs.readFileSync(path)) const actl = Buffer.alloc(20) actl.writeUInt32BE(8, 0) // length of chunk actl.write('acTL', 4) // type of chunk actl.writeUInt32BE(images.length, 8) // number of frames actl.writeUInt32BE(0, 12) // number of times to loop (0 - infinite) actl.writeUInt32BE(crc32(actl.slice(4, 16)), 16) // crc const frames = images.map((data, idx) => { const ihdr = findChunk(data, 'IHDR') const fctl = Buffer.alloc(38) fctl.writeUInt32BE(26, 0) // length of chunk fctl.write('fcTL', 4) // type of chunk fctl.writeUInt32BE(idx ? idx * 2 - 1 : 0, 8) // sequence number fctl.writeUInt32BE(ihdr.readUInt32BE(8), 12) // width fctl.writeUInt32BE(ihdr.readUInt32BE(12), 16) // height fctl.writeUInt32BE(0, 20) // x offset fctl.writeUInt32BE(0, 24) // y offset fctl.writeUInt16BE(1, 28) // frame delay - fraction numerator fctl.writeUInt16BE(1, 30) // frame delay - fraction denominator fctl.writeUInt8(0, 32) // dispose mode fctl.writeUInt8(0, 33) // blend mode fctl.writeUInt32BE(crc32(fctl.slice(4, 34)), 34) // crc const idat = findChunk(data, 'IDAT') // All IDAT chunks except first one are converted to fdAT chunks let fdat; if (idx === 0) { fdat = idat } else { const length = idat.length + 4 fdat = Buffer.alloc(length) fdat.writeUInt32BE(length - 12, 0) // length of chunk fdat.write('fdAT', 4) // type of chunk fdat.writeUInt32BE(idx * 2, 8) // sequence number idat.copy(fdat, 12, 8) // image data fdat.writeUInt32BE(crc32(4, length - 4), length - 4) // crc } return Buffer.concat([ fctl, fdat ]) }) const signature = Buffer.from('\211PNG\r\n\032\n', 'ascii') const ihdr = findChunk(images[0], 'IHDR') const iend = Buffer.from('0000000049454e44ae426082', 'hex') const output = Buffer.concat([ signature, ihdr, actl, ...frames, iend ]) fs.writeFileSync('output.png', output) 
Interesting Posts