Skip to content

Latest commit

 

History

History
215 lines (154 loc) · 9.44 KB

resize_zh.md

File metadata and controls

215 lines (154 loc) · 9.44 KB

Resize

翻译:English

Sketch 会调整图片的大小避免超出 Target 的需要造成内存浪费

调整图片大小依赖 ImageRequest 的 sizeResolver、precisionDecider、scaleDecider 属性,当他们都确定时会生成一个 Resize 交给 Decoder 使用

Decoder 先在解码时通过子采样或区域子采样降低图片大小,解码后如果大小依然不符合 Resize 要求就会再次调整

ResizeSizePrecisionScale 构成

  • Size:期望的宽和高
  • Precision:精度。决定如何使用 Size 去调整图片的大小
    • LESS_PIXELS:只要最终 Image 的像素数(宽乘以高)小于等于 Size 的像素数即可
    • SMALLER_SIZE:只要最终 Image 的宽和高都小于等于 Size 即可
    • SAME_ASPECT_RATIO:确保最终 Image 的宽高比和 Size 的宽高比一致并且像素数小于等于 Size 的像素数,如果不一致会根据 Scale 裁剪原图
    • EXACTLY:确保最终 Image 的大小和 Size 一致,如果不一致会根据 Scale 裁剪原图
  • Scale:缩放。Precision 为 EXACTLY 或 SAME_ASPECT_RATIO 时决定如何裁剪原图
    • START_CROP:保留头部部分
    • CENTER_CROP:保留中间部分
    • END_CROP:保留尾部部分
    • FILL:全部保留,但会变形

配置

ImageRequestImageOptions 都提供了 resize、size、precision、scale 方法用于配置 Resize,如下:

ImageRequest(context, "https://example.com/image.jpg") {
    /* 一次设置三个属性 */
    resize(
        width = 100,
        height = 100,
        precision = Precision.SAME_ASPECT_RATIO,
        scale = Scale.END_CROP
    )
    //
    resize(
        size = Size(100, 100),
        precision = LongImagePrecisionDecider(Precision.SAME_ASPECT_RATIO),
        scale = LongImageScaleDecider(longImage = Scale.START_CROP, otherImage = Scale.CENTER_CROP)
    )
    //
    resize(
        size = FixedSizeResolver(100, 100),
        precision = LongImagePrecisionDecider(Precision.SAME_ASPECT_RATIO),
        scale = LongImageScaleDecider(longImage = Scale.START_CROP, otherImage = Scale.CENTER_CROP)
    )

    /* 仅设置大小属性 */
    size(100, 100)
    //
    size(Size(100, 100))
    //
    size(FixedSizeResolver(100, 100))

    /* 仅设置精度属性 */
    precision(Precision.SAME_ASPECT_RATIO)
    //
    precision(LongImagePrecisionDecider(Precision.SAME_ASPECT_RATIO))

    /* 仅设置缩放属性 */
    scale(Scale.END_CROP)
    //
    scale(LongImageScaleDecider(longImage = Scale.START_CROP, otherImage = Scale.CENTER_CROP))
}

SizeResolver

Sketch 使用 Resolver 包装器为 ImageRequest 提供 Size,这是因为 View 或 Compose 组件的大小在构建 ImageRequest 时可能无法确定,需要等到绘制阶段才能获取,所以借助 SizeResolver 来解决这个问题

PrecisionDecider 和 ScaleDecider

Sketch 同样使用 Decider 包装器为 ImageRequest 提供 PrecisionScale ,这样就可以在解码时根据图片大小和 Resize 动态决定使用何种 PrecisionScale

默认提供了以下实现:

Tip

  1. 使用 LongImagePrecisionDeciderLongImageScaleDecider 有助于提高长图在网格列表中的清晰度。了解更多
  2. 长图规则的默认实现为 DefaultLongImageDecider,你还可以在创建 LongImagePrecisionDeciderLongImageScaleDecider 时使用自定义的规则

构建顺序和默认值

在构建 ImageRequest 时确定这些属性的值还是有些复杂的,如下:

Tip

  1. TargetViewTarget 时优先取 View 的 LayoutParams 宽高,其次延迟到绘制阶段取 View 的测量宽高,如果没有执行到绘制阶段那么请求也不会执行
  2. 假如组件的宽是固定值(例如 100),高是 wrap 时,Size 将会是 '100x屏幕或容器的高'
  3. 详细构建规则请参考 ImageRequest.Builder.build() 方法

PlatformContext.screenSize()

PlatformContext.screenSize() 方法用于获取屏幕的大小,构建 ImageRequest 时在无法获取 Size 的情况下会使用屏幕大小作为最终的 Size

Important

screenSize() 在非 Js 平台都能获取到准确的屏幕大小,但在 Js 平台会始终返回 Size(1920, 1080)

sizeMultiplier

sizeMultiplier 用于对 size 进行缩放,例如 sizeMultiplier 为 2.0 时,size 为 100x100 时实际 size 为 200x200

这通常用于默认用组件的大小作为 size,但是组件太小,需要放大 size 以提高图片质量,如下:

ImageRequest(context, "https://example.com/image.jpg") {
    sizeMultiplier(2.0f)
}

resizeOnDraw

ImageRequestImageOptions 的 resizeOnDraw 属性用于将 Resize 应用到 Target 的 placeholder, error, result Image 上,在绘制期间改变 Image 的大小

resizeOnDraw 依赖 ResizeOnDrawHelper 实现,ResizeOnDrawHelper 会用 ResizeDrawableResizePainter 将 placeholder, error, result Image 包一层,对外用 ResizeSize 作为宽和高,内部用 ResizeScaleImage 进行缩放

resizeOnDraw 搭配 CrossfadeTransition 可实现完美过渡。了解完美过度

Important

  1. ResizeOnDrawHelperTarget 提供,因此如果没有设置 Target,resizeOnDraw 属性也将无效