在画布上显示分层图像

您可以混合或叠加源图像以在画布上显示分层图像。例如,您可以通过组合单独的背景和前景可绘制对象来复制 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()
)

关于代码的关键点

  • 要组合的图像在使用OverlayImagePainter 组合之前,每个图像都作为ImageBitmap 实例加载。
  • 组合图像由一个Image 可组合项渲染,该可组合项使用自定义画家在渲染时组合源图像。

结果

Custom Painter that overlays two images on top of each other
图 1:一个Image,它使用自定义Painter 将半透明彩虹图像叠加到狗的图像上。

包含此指南的收藏夹

本指南包含在这些精选的快速指南收藏夹中,涵盖更广泛的 Android 开发目标

了解如何使用明亮、引人入胜的视觉效果来为您的 Android 应用提供美观的外观和感觉。

有疑问或反馈?

访问我们的常见问题页面,了解有关快速指南的信息,或与我们联系,告诉我们您的想法。