在画布上显示分层图片

您可以混合或叠加源图片,以便在画布上显示分层图片。例如,您可以通过组合单独的背景和前景可绘制对象来复制 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 应用打造美观的外观和风格。

有问题或反馈

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

API reference packages and classes for Android app developers.

更新于 Feb 10, 2025

API reference packages and classes for Android app developers.

更新于 Feb 10, 2025