Jetpack Compose中Image的ContentScale解析

说明

备注:本文仅做翻译及搬运,如有侵权,即删。如有错误,请指正。感谢作者,感谢开源。

出处:《Jetpack Compose Image Content ScaleType Fully Illustrated》

作者:elye

阅读须知

ImageView

在原有的Android XML视图中,我们可以指定各式各样的缩放模式来展示图片。但不同的模式可能会有相同的展示效果,为此让我我们会比较疑惑,接下来我们就各种情况进行剖析。

Android ImageView控件的缩放模式解析,请参考作者另一篇文章《Android ImageView ScaleType Fully Illustrated》
ContentScale解析 - 图1

ScaleType、ContentScale

先提前了解一下,在原有的Android View系统中,ImageView的缩放是ScaleType,在现在的Compose中,缩放是ContentScale,便于阅读下面文章进行区分

Jetpack Compose Image

在Jetpack Compose中,ContentScale策略有所不同, 它现在不再像ScaleType把缩放和对其合在一起操作,而是分成 2 个不同的属性,对其就是对其,缩放就是缩放,如下面的代码所示。

Image(imagePicture,
contentDescription = null,
modifier = Modifier.fillMaxSize(),
alignment = alignment.alignment,
contentScale = scale.scaleType

)
对于我们而言这是件好事儿,我们只关心图片本身的缩放,而不用再去考虑对其方式,对其交给alignment处理就好:

  • 在原来的ImageView中,我们会在xml设置 FitStart、FitEnd 和 FitCenter,但在Jetpack Compose 中,我们只需要Fit,通过Alignment来实现Start、End、Center的效果
  • 在原来的ImageView中,ImageView只有CenterCrop,没有“StartCrop”、“EndCrop”属性,(要实现这种效果,可以参考下面的文章《Android Image StartCrop and EndCrop Scaling》),但是在Jetpack Compose 中,我们可以结合CropAlignment属性,实现“StartCrop”、“EndCrop”效果。

ContentScale解析 - 图2

ContentScale和ScaleType的对比

如果你对ImageView的ScaleType比较熟悉,那么下面这张对比图应该很容易理解
ContentScale解析 - 图3

从上表可以看到,ScaleType仅仅覆盖了ContentScale7种模式中的5种。ContentScaleFitWidthFitHeight并不在其中,是因为这两种属于ScaleType并不直接支持。
如果需要在ImageView中精确的实现“FitWidth”“FitHeight”两种效果,可以参考下面示例图:
ContentScale解析 - 图4

ContentScale.FillHeight

ContentScale.FillHeight模式下,它将确保图片的高度达到视图的上下边界

  • 如果图片的高度大于宽度FillHeight则等效ScaleType.FitCenter,图片左右两侧会有留白
  • 如果图片的高度小于宽度FillHeight则等效ScaleType.CenterCrop,图片超出的宽度会被剪裁

ContentScale解析 - 图5

ContentScale.FillWidth

ContentScale.FillWidth模式下,它将确保图片的宽度达到视图左右边界

  • 如果图片的高度大于宽度FillWidth则等效于ScaleType.CenterCrop,超出的高度会被裁剪
  • 如果图片的高度小于宽度FillWidth则等效于ScaleType.FitCenter,图片上下两侧会留白

ContentScale解析 - 图6
简而言之,对图片的缩放处理,Jetpack Compose的ContentScale更为基础实用。

ContentScale使用教程

很多时候,ContentScale的各个属性使用起来会有相同的想过,让人疑惑费解,接下来我将通过4中不同尺寸的图片进行举例说明

  • Bigger Image: 图片宽高均大于设备宽高,详见瀑布图片
  • Smaller Image: 图片宽高均小于设备宽高,详见狮子图片
  • Taller Image: 图片高度大于设备高度,宽度小于设备宽度,详见椰子树图
  • Longer Image: 图片高度小于设备高度,宽度大于设备宽度,详见长桥图片

ContentScale解析 - 图7

ContentScale.Inside

ContentScale.Inside属性会有以下效果:

  • 保持图片原始宽高比
  • 保证图片都显示在视图内,但可能会上下、左右留白
  • 图片不会被拉伸、裁剪

ContentScale解析 - 图8

ContentScale.Crop

ContentScale.Crop属性会有以下效果:

  • 保持图片原始宽高比(非视图展示效果,多余部分会被裁剪,所以看起来不像是原图的宽高比)
  • 图片可能会等比被缩小,直到宽高均占满视图宽高的边界
  • 图片可能会被等比放大,直到宽高均占满视图宽高的边界
  • 控件上下或者左右两边不会有留白
  • 超出控件边界的内容会被裁剪

ContentScale解析 - 图9

ContentScale.Fit

ContentScale.Fit属性会有以下效果:

  • 保持图片原始宽高比
  • 如果图片高度大于空间高度,等比缩小图片保证图片高度与控件的上下边界重合
  • 如果图片宽高小于空间宽高,等比放大图片直到有一边能与控件的上下或左右边界重合
  • 控件的上下或者左右可能会有留白
  • 图片不会被裁剪

ContentScale解析 - 图10

ContentScale.FillBounds

ContentScale.FillBounds属性有以下效果

  • 不会保持图片的原始宽高比
  • 如果图片大小大于控件大小,图片会被缩小直到每一边与控件边界重合
  • 如果图片大小小于控件大小,图片会被拉伸直到每一边与控件边界重合
  • 控件上下左右边界不会有留白
  • 图片不会被裁剪

ContentScale解析 - 图11

ContentScale.FillHeight

ContentScale.FillHeight属性有以下效果

  • 保持图片原始宽高比
  • 图片可能会按照原始宽高等比缩小,直到高度与控件上下边界重合
  • 图片可能会按照原始宽高等比放大,直到高度与控件上下边界重合
  • 如果图片宽度小于高度,则控件左右边界会有留白
  • 如果图片宽度大于高度,则左右多余部分会有裁剪

ContentScale解析 - 图12

ContentScale.FillWidth

ContentScale.FillWidth属性有以下效果:

  • 保持图片原始宽高比
  • 图片可能会按照原始宽高等比缩小,直到宽度与控件左右边界重合
  • 图片可能会按照原始宽高等比放大,直到宽度与控件左右边界重合
  • 如果图片宽度大于高度,则控件上下边界会有留白
  • 如果图片宽度小于高度,则上下多余部分会有裁剪

ContentScale解析 - 图13

可以通过下面几张效果图,快速一览同一张图片,不同ContentScale下的展示效果
ContentScale解析 - 图14
ContentScale解析 - 图15

总结

为了简化ContentScale的描述,我制作了下面这张表格
ContentScale解析 - 图16
根据项目实际需求,你可以从图中选择想要的效果。
希望这篇文章对于你使用ContentScale有用.
github demo源码

ContentScale解析 - 图17