PNG 相关

玩玩竞赛扩充下知识还是很不错的,虽然都不会23333。

平常接触最多的就是 png 格式的图片格式了。但是没有好好了解过。

简介

https://zh.wikipedia.org/wiki/PNG

简单看下一些特性:

  • 支持256色调色板技术以产生小体积文件
  • 最高支持24位真彩色图像以及8位灰度图像。
  • 支持Alpha通道的透明/半透明特性。
  • 支持图像亮度的Gamma校准信息。
  • 支持存储附加文本信息,以保留图像名称、作者、版权、创作时间、注释等信息。
  • 使用无损压缩。
  • 渐近显示和流式读写,适合在网络传输中快速显示预览效果后再展示全貌。
  • 使用CRC防止文件出错。
  • 最新的PNG标准允许在一个文件内存储多幅图像。

数据与结构

图片是属于2进制文件,以二进制的方式进行读取操作。

PNG图像格式文件由一个8字节的PNG文件标识(file signature)域和3个以上的后续数据块(chunk)组成。

文件标识: (89 50 4E 47 0D 0A 1A 0A,十六进制)

PNG定义了两种类型的数据块:一种是PNG文件必须包含、读写软件也都必须要支持的关键块(critical chunk);另一种叫做辅助块(ancillary chunks),PNG允许软件忽略它不认识的附加块。

关键数据块中有4个标准数据块:

  • 文件头数据块IHDR(header chunk):包含有图像基本信息,作为第一个数据块出现并只出现一次。
  • 调色板数据块PLTE(palette chunk):必须放在图像数据块之前。
  • 图像数据块IDAT(image data chunk):存储实际图像数据。PNG数据允许包含多个连续的图像数据块。
  • 图像结束数据IEND(image trailer chunk):放在文件尾部,表示PNG数据流结束。
const fs = require('fs')  
const bf = fs.readFileSync('ori.png')

function readBytes(buffer, begin, length) {  
    return Array.prototype.slice.call(buffer, begin, begin + length);
}

let sign = readBytes(pngBuffer, 0, 8); // [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]  

几个关键 API: