Cómo mostrar imágenes en capas en un lienzo

Puedes combinar o superponer imágenes de origen para mostrar imágenes en capas en un lienzo. Por ejemplo, puedes replicar la forma en que el framework de Android genera íconos de apps combinando elementos de diseño de primer y segundo plano separados. Para mostrar imágenes en capas, debes hacer lo siguiente:

  • Superponer imágenes en un lienzo
  • Superpone la fuente.

Compatibilidad de versiones

Esta implementación requiere que el minSDK de tu proyecto se establezca en el nivel de API 21 o superior.

Dependencias

Cómo superponer imágenes en un lienzo

En el siguiente código, se superponen dos imágenes de origen para renderizar una imagen combinada en el lienzo:

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
    }
}

Puntos clave sobre el código

  • Usa OverlayImagePainter, que es una implementación personalizada de Painter que puedes usar para superponer imágenes sobre la imagen de origen. El modo de combinación controla cómo se combinan las imágenes. La primera imagen no reemplaza nada, por lo que no se necesita ningún modo de combinación. El modo de combinación Overlay de la segunda imagen reemplaza las áreas de la primera imagen que cubre la segunda.
  • Se anula DrawScope.onDraw() y las dos imágenes se superponen en esta función.
  • Se anula intrinsicSize para informar correctamente el tamaño intrínseco de la imagen combinada.

Superposición de la imagen de origen

Con este pintor personalizado Painter, puedes superponer una imagen sobre la imagen de origen de la siguiente manera:

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()
)

Puntos clave sobre el código

  • Cada una de las imágenes que se combinarán se carga como instancias de ImageBitmap antes de combinarse con OverlayImagePainter.
  • Las imágenes combinadas se renderizan con un elemento componible Image que usa el pintor personalizado para combinar las imágenes de origen durante la renderización.

Resultados

Pintor personalizado que superpone dos imágenes una sobre la otra
Figura 1: Un Image que usa un Painter personalizado para superponer una imagen de arco iris semitransparente sobre la imagen de un perro.

Colecciones que contienen esta guía

Esta guía forma parte de estas colecciones de guías rápidas seleccionadas que abarcan objetivos más amplios de desarrollo de Android:

Descubre técnicas para usar imágenes atractivas y brillantes que le den a tu app para Android un aspecto atractivo.

Tienes preguntas o comentarios

Ve a nuestra página de preguntas frecuentes para obtener información sobre las guías rápidas o comunícate con nosotros para contarnos tu opinión.