农村的师傅的博客

一个迫于生计,无法放飞自我,导致喜欢上了前端开发,并即将成长为强者(指头发)的程序猿。

0%

数字切片文件格式了解

这篇文章主要记录一下我对数字切片格式的一些理解。

下面介绍的相关内容,其实不止是适用于数字切片文件,也适用于地图或者其他任何高分辨率图像文件。

数字切片文件图像数据存储方式

数字切片说白了是为了将一张很大的图片存起来,并方便的一种存储方式。一个数字切片文件是为了存储了一张很大的图像信息,并为了方便浏览该图像,存储了一些额外数据和信息。

一般图像存储方式有几种,先不管其压缩如何,图像压缩只是对图像数据的一种压缩,而图像本身的存储也是分为几种方式,常见的有条状和瓦片两种。我们后续都以栅格图像为示例说明(即由像素点组成的图像)

条带图像

假设有一个100x100像素的图像,那么你可以选择将图像数据存储为条状的,在你知道图像的宽高的情况下,图像的像素数据从左到右,从上到下,以这种顺序的方式以将图像的像素数据进行存储,表现形式可以理解为一个存放图片像素数据的数组。这就是图像的条状存储方式。通常普通大小图片都是按这种方式进行存储的。

瓦片图像(平铺图像)

大图像加载

而一张10wx10w的图像,上面的条状图像存储方式就不太合适了。不是条状图像方式无法存储,而是说,以条状方式存储图像时,无法方便我们浏览如此大的图像。

首先,不管用何种方式存储该图像,我们都无法直接加载并浏览完整的该图像,因为图像太大,无法直接加载浏览。假设,如果单纯的考虑图像的一个像素由rgb组成,一个像素的r或g或b分别都占1字节(0-255),然后一个100x100像素的图像所需要的字节数为:100x100x3字节。而一个10wx10w的图像,其字节数为:10w x 10w x 3 字节数,大约为27GB,我们知道,图像压缩只是为了存储和传输,而真正显示时,还是会将完整的图像数据加载到内存,而完整的图像数据所占据的空间太大,,通常计算机都无法将其完全加载到内存中。

大图像浏览

所以我们对于大图像的浏览,需要换一种方式,我们的屏幕大多为1920x1080,而完整的10wx10w像素的图像,它远远大于我们屏幕大小,在图像没有缩放时,我们的屏幕只能显示整个图像中的一部分,但我们能看到图像中清晰的图案。既然如此,我们在浏览如此大的图像时,只需要加载它只在显示屏中出现的那部分图像即可。其他部分我们可以不需要加载,这样就无须让计算机加载完整的图像数据到内存中了。

而条状存储方式在这种图像浏览场景下就不太适合了,因为你加载一部分图像时,会额外加载无用的图像。

瓦片图像的存储方式

瓦片图的形式,其实就是将图像分割为一块一块的矩形小图,这些小图称之为瓦片图,并且我们会将每个瓦片图属于原始大图的位置信息记录下来。每个瓦片图作为一个普通的图像以条带的形式进行存储。而每个瓦片图都是独立的,独立的压缩方式、独立的数据,各个瓦片图图像数据之间没有太大关联,这样,我们可以计算出某个大图中某个区域包含了哪些瓦片图数据,并仅加载这些瓦片图即可。

数字切片文件图像层级

不同分辨率的图像层级

上面中的图像存储方式仅解决了大图像浏览时的图像加载问题,我们用瓦片图的形式,让用户在浏览图像时,仅加载浏览的那一部分图像区域的图像数据。而上面的示例也只是在图像的最大分辨率下进行的,且只能满足平移图像时的浏览需求(移动到不同的图像位置,就加载图像那个位置的那部分瓦片图)。但是我们在看图像时,不可能只有图像的平移,还需要拥有缩放,如果我们只在最大那一层去浏览图像的话,一次只能看到图像很小的一部分,因为我们的浏览视图窗口大小是有限的。我们有时需要能查看整个图像的全貌。

浏览大图时的图像缩放

图像倍数越放大,越能显示细节,但是显示的图像内容越少,视野越小。图像倍数越缩小,细节越模糊,但是显示的图像内容越多,视野越大。

假设我想要看整个图像的全貌,就在有限的浏览视图窗口下,那怎么做?其实就是缩放图像到视窗口大小即可,这是基本上所有图像浏览工具必备的一个功能,大图像的查看也需要这个功能。

此时会出现一个问题,假设用户将整个大图缩放到只有视图窗口大,那么你需要加载多少瓦片图?因为图像的所有区域都出现在视窗口下了,按理来说,需要加载所有的瓦片图数据,因为缩放图像不可能凭空缩放,只能是从原图像数据,缩放到某一个大小的,而在此之前,需要加载原图数据,即完整的那张大图像。而之前我们也说过,加载如此大的一张大图到计算机中是不现实的。

那我们可以换一种思路,我们可以预先帮用户生成不同缩放倍数下的不同分辨率的图像(即有多个不同分辨率的图像),当用户将图像缩放到某一个倍数时,加载适合该缩放倍数的那个分辨率的图像,而不是任意倍数都加载最大分辨率的那个图像。通常,原始分辨率的那个图像是最大分辨率的图像,而其他更小的分辨率图像都是用这个图像缩放得来的,且在生成图像文件时,就已经处理好了。也就是:除了原始的最大分辨率图像之外,还有基于这个最大分辨率图像缩放而来的多个不同分辨率的小图像。

这样,用户在浏览不同缩放倍数下的图像时就都有分辨率较为合适的图像了。这其实就是所谓的图像金字塔,以及它的作用。

通常每个层级图像的宽高分辨率之间是2分之一或者4分之一(假设1000x1000分辨率的图像,比它小的那一层图像分辨率就为:500x500-2分之一或者250x250-4分之一,更小的那层就再缩小为2分之一或者四分之一)这个是有说法的,因为我们在浏览时缩放数字,可以支持任意缩放,我们不可能每个缩放倍数都存在相应分辨率的图像的,所以,浏览图像时,浏览软件会根据当前用户当前的缩放倍数,根据一个阈值加载适合当前倍数的分辨率的图像,然后再根据这个加载的图像,缩放到相应的真正倍数。

最大分辨率的图像即为原始图像,其他更小分辨率的图像都是由这个图像缩放而来的。其实其他小分辨率图像,只是为了方便对图像进行浏览而存在的冗余数据。

推荐资料

推荐看一下svs官方文档中Single File FormatsPanning and Zooming章节,里面说明了条带图像和瓦片图像以及他们在图像浏览的缩放和平移中如何加载图像的一些介绍:https://web.archive.org/web/20120420105738/http://www.aperio.com/documents/api/Aperio_Digital_Slides_and_Third-party_data_interchange.pdf

数字切片文件

其实数字切片对于用户来说,表示的就是一个图像。就和png就是表示一张图,数字切片文件表示的也是一张图,供用户浏览用的。只不过这个图像很大。

一个完整的数字切片,在设计时,为了方便用户浏览该数字切片,它拥有以下几个特点:

  • 它包含了从大到小的不同分辨率的同一图案的多个图像,也就是所谓的图像层级或者切片层级
  • 每个分辨率的图像,不管分辨率大小,都是由瓦片图的方式组成。且不同分辨率图像分割的瓦片图大小是一致的

数字切片相关文件的格式

数字切片文件的格式有挺多的,比如svskfbsdpc等等,不过其实这些理解为文件后缀名更加合适,文件格式其实是数据的组织方式。

比如svs文件是Aperio公司出品一个基于TIFF文件格式的图像文件类型。具体可以参考:svs数字切片调研

简单来说,数字切片是需要存储如下数据:

  • 多个不同分辨率大小的图像,每个图像都以瓦片图的方式进行组织
  • 存储组织该这些图像的信息数据,比如某个分辨率图像中的某个瓦片图数据所在的位置和一些信息等。
  • 切片文件除了存储图像相关数据之外,还需要存储表示该物理切片的一些基本信息

文件本身就是连续的字节数据,文件格式就是这些字节数据的组织规范

切片文件大小

因为数字切片存储的图像数据,而且是包含了多个不同分辨率的图像,最大分辨率的图像在几万到上10万的像素宽高。我们上面算过:一个10wx10w的图像,其字节数为:10w x 10w x 3 字节数,大约为27GB,而且这还只是最大分辨率的图像,还有其他不同分辨率的图像。即使图像可以进行压缩,但是,压缩率也是有限的,

影响切片文件大小的因素通常有下面两个方面,而且通常都是和图像数据相关的,因为数字切片主要是存储的图像数据,图像数据占据几乎99%:

图像压缩方式

一个是图像的压缩方式,不同的图像压缩方式,比如jpeg、hevc等,其生成的数字切片大小是不一样的,hevc的压缩率能够比jpeg更好,所以,以hevc来压缩图像的数字切片大小比jpeg来压缩图像的要小。

不同分辨率图像的多少

另外一个是切片中,不同分辨率的图像个数,我们知道,一个切片中除了原始的最大分辨率图像之外,还有基于这个最大分辨率图像缩放而来的多个不同分辨率的小图像。而这些小的分辨率图像的多少,影响切片文件大小。

怎么理解呢,因为除了最大分辨率的图像,之外,我们还需要由最大分辨率缩放而来的小图像,而每次的缩放比为2分之一或者4分之一,以同一个最大分辨率(10000的宽高)的图像为例:

缩放比:2分之一

  • 图像一宽高:10000
  • 图像二宽高:5000
  • 图像三宽高:2500
  • 图像四宽高:1250
  • 图像五宽高:625

缩放比:4分之一

  • 图像一宽高:10000
  • 图像二宽高:2500
  • 图像三宽高:625

有上面可知,缩放比四分之一相比二分为之一,少了一些图像,因为缩放,总会有一个尽头,通常是小于一定的分辨率就没必要再缩放了,而缩放比为四分之一,相比于二分之一,其差异就是少了某些分辨率的图像而已,那么某些分辨率的图像少了,自然就没有必要存储这些图像数据,自然就可以减小切片文件的体积了。

这里仅仅只是举个缩放例子,实际情况图像原始大小其实并没有那么标准,那么这里其实是需要为每一层图像进行补白处理的。比如一张切片的瓦片图定义为256*256大小,而这张切片某个图像层级的宽高可能不是256的倍数,那么其实需要将图像进行补白,以符合256的倍数,这样就能分割瓦片图了。