一、Android 尺寸压缩逻辑
针对图片尺寸的修改其实就是一个图像重新采样的过程,放大图像称为上采样(upsamping),缩小图像称为下采样(downsampling),这里我们重点讨论下采样。
在 Android 中图片重采样提供了两种方法,一种叫做邻近采样(Nearest Neighbour Resampling),另一种叫做双线性采样(Bilinear Resampling)。
除了 Android 中这两种常用的重采样方法之外,还有另外比较常见的两种:双立方/双三次采样(Bicubic Resampling) 和 Lanczos Resampling。除此之外,还有一些其他个人或机构发明的算法 Hermite Resampling,Bell Resampling,Mitchell Resampling。我们这里着重介绍前面提到的四种采样方法。
二、邻近采样(Nearest Neighbour Resampling)
Nearest Neighbour Resampling(邻近采样),是 Android 中常用的压缩方法之一,我们先来看看在 Android 中使用邻近采样的示例代码:
来看看邻近采样的图片效果:
图是每个像素红绿相间的图片,可以看到处理之后的图片已经完全变成了绿色,接着我们来看看 inSampleSzie 的官方描述:
从官方的解释中我们可以看到 x(x 为 2 的倍数)个像素最后对应一个像素,由于采样率设置为 1/2,所以是两个像素生成一个像素。邻近采样的方式比较粗暴,直接选择其中的一个像素作为生成像素,另一个像素直接抛弃,这样就造成了图片变成了纯绿色,也就是红色像素被抛弃。
邻近采样采用的算法叫做邻近点插值算法。
三、双线性采样(Bilinear Resampling)
双线性采样(Bilinear Resampling)在 Android 中的使用方式一般有两种:
看源码可以知道 createScaledBitmap 函数最终也是使用第二种方式的 matrix 进行缩放,我们来看看双线性采样的表现:
可以看到处理之后的图片不是像邻近采样一样纯粹的一种颜色,而是两种颜色的混合。双线性采样使用的是双线性內插值算法,这个算法不像邻近点插值算法一样,直接粗暴的选择一个像素,而是参考了源像素相应位置周围 2x2 个点的值,根据相对位置取对应的权重,经过计算之后得到目标图像。
双线性内插值算法在图像的缩放处理中具有抗锯齿功能, 是最简单和常见的图像缩放算法,当对相邻 2x2 个像素点采用双线性內插值算法时,所得表面在邻域处是吻合的,但斜率不吻合,并且双线性内插值算法的平滑作用可能使得图像的细节产生退化,这种现象在上采样时尤其明显。
四、邻近采样和双线性采样对比
我们这里来对比一下这两种 Android 中经常用到的图片尺寸压缩方法。
邻近采样的方式是最快的,因为它直接选择其中一个像素作为生成像素,但是生成的图片可能会相对比较失真,产生比较明显的锯齿,最具有代表性的就是处理文字比较多的图片在展示效果上的差别,对比:
原图:
邻近采样:
双线性采样:
这个对比就非常直观了,邻近采样字的显示失真对比双线性采样来说要严重很多。
五、双立方/双三次采样(Bicubic Resampling)
双立方/双三次采样使用的是双立方/双三次插值算法。邻近点插值算法的目标像素值由源图上单个像素决定,双线性內插值算法由源像素某点周围 2x2 个像素点按一定权重获得,而双立方/双三次插值算法更进一步参考了源像素某点周围 4x4 个像素。
本文为授权转载文章,任何人未经原授权方同意,不得复制、转载、摘编等任何方式进行使用,e-works不承担由此而产生的任何法律责任! 如有异议请及时告之,以便进行及时处理。联系方式:editor@e-works.net.cn tel:027-87592219/20/21。