在画布上显示分层图片

您可以混合或叠加源图片,以便在画布上显示分层图片。例如,您可以通过组合单独的背景和前景可绘制对象来复制 Android 框架生成应用图标的方式。如需显示分层图片,您必须执行以下操作:

  • 在画布上叠加图片。
  • 叠加来源。

版本兼容性

此实现要求将项目 minSDK 设置为 API 级别 21 或更高级别。

依赖项

在画布上叠加图片

以下代码会将两张源图片叠加在一起,在画布上渲染经过混合的图片:

class OverlayImagePainter constructor(
    private val image: ImageBitmap,
    private val imageOverlay: ImageBitmap,
    private val srcOffset: IntOffset = IntOffset.Zero,
    private val srcSize: IntSize = IntSize(image.width, image.height),
    private val overlaySize: IntSize = IntSize(imageOverlay.width, imageOverlay.height)
) : Painter() {

    private val size: IntSize = validateSize(srcOffset, srcSize)
    override fun DrawScope.onDraw() {
        // draw the first image without any blend mode
        drawImage(
            image,
            srcOffset,
            srcSize,
            dstSize = IntSize(
                this@onDraw.size.width.roundToInt(),
                this@onDraw.size.height.roundToInt()
            )
        )
        // draw the second image with an Overlay blend mode to blend the two together
        drawImage(
            imageOverlay,
            srcOffset,
            overlaySize,
            dstSize = IntSize(
                this@onDraw.size.width.roundToInt(),
                this@onDraw.size.height.roundToInt()
            ),
            blendMode = BlendMode.Overlay
        )
    }

    /**
     * Return the dimension of the underlying [ImageBitmap] as it's intrinsic width and height
     */
    override val intrinsicSize: Size get() = size.toSize()

    private fun validateSize(srcOffset: IntOffset, srcSize: IntSize): IntSize {
        require(
            srcOffset.x >= 0 &&
                srcOffset.y >= 0 &&
                srcSize.width >= 0 &&
                srcSize.height >= 0 &&
                srcSize.width <= image.width &&
                srcSize.height <= image.height
        )
        return srcSize
    }
}

代码要点

  • 使用 OverlayImagePainter,这是一种自定义 Painter 实现,可用于在源图片上叠加图片。混合模式用于控制图片的组合方式。第一个图片不会覆盖任何其他内容,因此无需混合模式。第二张图片的 Overlay 混合模式会覆盖第二张图片覆盖的第一张图片的区域。
  • 此函数会替换 DrawScope.onDraw(),并将这两张图片叠加在一起。
  • 替换了 intrinsicSize,以正确报告合并图片的固有尺寸。

叠加源图片

借助此自定义画家 Painter,您可以在源图片之上叠加图片,如下所示:

val rainbowImage = ImageBitmap.imageResource(id = R.drawable.rainbow)
val dogImage = ImageBitmap.imageResource(id = R.drawable.dog)
val customPainter = remember {
    OverlayImagePainter(dogImage, rainbowImage)
}
Image(
    painter = customPainter,
    contentDescription = stringResource(id = R.string.dog_content_description),
    contentScale = ContentScale.Crop,
    modifier = Modifier.wrapContentSize()
)

代码要点

  • 要合并的图片会分别加载为 ImageBitmap 实例,然后再使用 OverlayImagePainter 合并。
  • 合并后的图片由 Image 可组合项渲染,该可组合项在渲染时使用自定义绘制程序组合源图片。

结果

将两张图片相互叠加的自定义 Painter
图 1:使用自定义 Painter 将半透明的彩虹图片叠加在狗的图片上的 Image

包含本指南的集合

本指南属于以下精选快速入门集合,这些集合涵盖了更广泛的 Android 开发目标:

了解如何使用明亮动人的视觉元素为 Android 应用打造美观的外观和风格。

有问题或反馈

请访问我们的常见问题解答页面,了解简短指南,或与我们联系,告诉我们您的想法。