开通VIP,畅享免费电子书等14项超值服
首页
好书
留言交流
下载APP
联系客服
2021.10.17
HighEfficiencyImageFileFormat(HEIF,发音为:heef),由MovingPictureExpertsGroup(MPEG,即动态图像专家组)于2013年开发,它基于ISOBMFF标准。HEIF是一个容器的图片格式,它可以包含图片和图片序列(一个文件可以包含不止一个图片)。当前的编码格式有:HEVC和H.264/MPEG-4AVC两种,并且未来可能有新的编码格式加入。
问题一:HEIF和heic有什么关联呢?
答:.heic只是一个HEIF文件格式的一种扩展名,言外之意是:HEIF不仅有.heic这种扩展名,还有其它的,比如说:.heif和.avci,它们都是属于HEIF文件格式。当然,常见的只有.heif和.heic这两种,而.avci很少见。在苹果的实现中,单个图片采用.heic文件扩展名,它默认使用的都是HEVC的编码格式。当然,苹果官方未来会对H.264/MPEG-4AVC编码的.avci文件进行支持,以及.heif文件。
两种编码格式如下所示:
Figure1:引用自网络,侵删。
2.1Rasterandvectorimages位图和矢量图
矢量图(vectorimage):
Figure2:引用自heikkila,p13
它们都是通过数学公式计算获得的,如上图。由轮廓的方向、曲率、粗细以及轮廓和填充的颜色等数学模型决定的图形叫矢量图,图形可以无限放大,不变色、不模糊。
位图(rasterimage,bitmapimage):
位图是由称作像素(图片元素)的单个点组成的图像,上图可以用5*5的对角矩阵去存储,空白记为0,黑色块记为1。HEIF格式只支持位图。
2.2色深(bitdepth)
描述每个像素填充信息的参数称为色深,bitdepth通常有1bit~64bit。特别的,对于只有1bit的.由0或1组成的双色,通常是黑白的灰度图像。Bitdepth最常见的是24bit,红蓝绿各占8位。□□□□□□□□□□□□□□□□□□□□□□□□换句话说,对于一个bitdepth为24的图片,它的每个像素有2^24种可能。
2.3元数据(Metadata)
2.4当前存在的位图格式(Currentrasterimageformats)
旧的文件格式有:Gif,PNG,TIFF,JPEG较新的格式包括:WebP和BPG,还有HEIF
GIF:1987年引入,前身是基于RLE编码的图片格式VIDTEX.1989年,GIF更新到支持动画和透明。开始采用有损压缩方式:色块从24位调色板中生成了256种颜色,采用LZW编码(它有第三方专利)GIF不是一个储存图片的很好选择,因为对于每个色块而言,它可选的颜色太过有限。
PNG:1995提出,PNG作为GIF的替代,意图是创建一个免专利费的图片格式。1996第一个说明文档发布。它提供更好的压缩,更真的颜色支持,可选的alpha通道透明度。2004年发布了IOS标准,png成了互联网上最受欢迎的有损图片格式。
TIFF:TaggedImageFileFormat
JPEG:JointPhotographicExpertsGroup1992年第一个JPEG标准,1994年成为ISO标准JPEG2000在2000年成为一个国际标准,目的是取代92年的JPEG标准。JPEG2000需要更高的计算资源,且不向后兼容,到2016年仍有许多浏览器和图片应用缺少对它的支持。
WebP:Google在2010年引入。
定义了盒子结构(box-structured)文件,意味这数据被分配在这些盒子中。
允许盒子中包含其他盒子。
每个盒子的头部包含着盒子类型的信息,和这个盒子的大小。
这样做使之成为可能:读程序可以跳过不必要的信息和不支持的盒子
使用4个ASCII码作为不同的入口,标示盒子的类型。这些4字节通常称为FourCCor4CC。
注:大多数人使用术语容器,而“盒子”的说法,此处仅个人习惯。
如上图,从最外层看,它有四层盒子类型的结构,分别是:
ftyp
meta
moov
mdat
关于上述4层结构的功能,如下:
ftyp:它总是HEIF文件的开头,它以brand参数描述了文件的类型和兼容性。
ftpy的底层实现,例如:
仅单张image的图片:一个单图片hevc编码且有Exif的文件,可能的结构如下:
衍生的图片:HEIF一个灵活的特性就是支持派生图像(derivedimages)。所谓的派生图像有两种方式1.一种方式恒等派生(identityderivation),通过为图像分配转换属性来创建。比方说,既有一个图片,也有一个翻转版本的图片提供给该用户。2.另一种是通过来自imageitems的图片网格(imagegrid)+图像布局(imageoverlay)来派生。一个图片网格,允许其图块旁边邻接着其它图块。
moov:如果一个图片文件包含了图片序列,则存储在这里面。它包含了很多Trackboxed,每个盒子代表一个图片序列。
mdat:无论是单张图片还是图片序列,其图片数据都存储在mdat盒子。一个文件里面可以包含多个mdat盒子。示例如下:
Exif元数据
thumbnail缩略图
HEVC编码后的图片
苹果的heic格式文件,就是衍生方式实现的典范。苹果并不是直接把一张图片item存储在一个盒子中,而是它把图片按网格(grid)拆分成图块(tiles),按图块去分别存储在每个mdat盒子中。
下面给出一个示例,这个主图片的数据是从三个预先编码的图片item中衍生出来的。这个4个图块有同样的宽度和高度。
实际上对于苹果的.heic文件的图片,图片一般由512*512这种的图块(tiles)构成。然后按照从左到右,从上到下的顺序,依次将图块存入HEIF图像序列。假设如果这个图片如果刚好不是图块(tiles)的偶数倍,那么图片的右边和底部将用黑色填充。苹果也建议用这些帧的整数倍去构成图片。对于一个iphone7上典型的4032×3024分辨率图片,如下图所示,苹果将这个图片以这种方式存储:
把这个图片分成8*6的块,行8,列6。(我测试的时候好像发现了也有7*5的图片)
其余的部分用黑色的块去填充。
Figure7:引用自liuziangexit@github.
问题二:为什么上面说“其余的部分”?
答:因为对于这个4032*3024的heif图片,它的每个图块大小是512*512,而4032*3024不是512*512的整数倍。请参考下面的计算:
4032*3024=12192768512*512*46=1205862446个网格,不足以容纳全部像素。512*512*48=1258291248个网格,足够,但需要填充。问题三:苹果为什么要以图块的方式存储?
答:
苹果的官方幻灯片提供了解释:
Figure8:引用自Apple
我的理解是:1.方便多线程可以并行处理,这样更快,因为每个图块可以单独解码。2.降低内存开销。单张的静态图片对手机的HEVC解码器而言太大,所以把它分成图块处理可以更好。3.便于裁剪。
HEIF文件的写入和解析,已经由诺基亚的技术人员已经实现了(C++)。感谢这些聪明+勤奋的工程师们!链接如下:
原理:HEIF文件的读写,本质上是对盒子的处理。在更低的层次上说,就是如何去处理ISOBMFF标准设计的BitStream类。规则是: