Cómo mostrar una imagen recortada en una forma

Puedes ajustar una imagen a una forma recortada y dibujar sombras alrededor del perímetro de la forma para darle un aspecto tridimensional. Esta técnica es útil para crear diseños, como avatares y miniaturas de productos, o mostrar logotipos con formas personalizadas.

Para mostrar una imagen recortada en una forma, debes hacer lo siguiente:

  • Crea la forma.
  • Recorta la imagen según la forma.

Resultados

Perro en hexágono con sombra aplicada alrededor de los bordes
Figura 1: Se aplicó una forma personalizada como clip.

Compatibilidad de versiones

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

Dependencias

Crea una forma

El siguiente código crea una forma personalizada que puede dibujar y renderizar de forma dinámica un polígono redondeado:

fun RoundedPolygon.getBounds() = calculateBounds().let { Rect(it[0], it[1], it[2], it[3]) }
class RoundedPolygonShape(
    private val polygon: RoundedPolygon,
    private var matrix: Matrix = Matrix()
) : Shape {
    private var path = Path()
    override fun createOutline(
        size: Size,
        layoutDirection: LayoutDirection,
        density: Density
    ): Outline {
        path.rewind()
        path = polygon.toPath().asComposePath()
        matrix.reset()
        val bounds = polygon.getBounds()
        val maxDimension = max(bounds.width, bounds.height)
        matrix.scale(size.width / maxDimension, size.height / maxDimension)
        matrix.translate(-bounds.left, -bounds.top)

        path.transform(matrix)
        return Outline.Generic(path)
    }
}

Puntos clave sobre el código

  • RoundedPolygon.getBounds() define una función de extensión en la clase RoundedPolygon para calcular sus límites.
  • La clase RoundedPolygonShape implementa la interfaz Shape, lo que te permite definir una forma personalizada (un polígono redondeado) en Jetpack Compose.
  • La forma usa un Matrix para administrar las operaciones de escalamiento y traslación para una renderización flexible.
  • La función createOutline() toma un objeto RoundedPolygon, lo ajusta y lo traduce para que quepa dentro de un tamaño determinado, y devuelve un objeto Outline que describe la forma final que se dibujará.

Recorta la imagen en una forma

El siguiente código recorta la imagen en un hexágono y agrega una sombra paralela sutil para brindar una sensación de profundidad:

val hexagon = remember {
    RoundedPolygon(
        6,
        rounding = CornerRounding(0.2f)
    )
}
val clip = remember(hexagon) {
    RoundedPolygonShape(polygon = hexagon)
}
Box(
    modifier = Modifier
        .clip(clip)
        .background(MaterialTheme.colorScheme.secondary)
        .size(200.dp)
) {
    Text(
        "Hello Compose",
        color = MaterialTheme.colorScheme.onSecondary,
        modifier = Modifier.align(Alignment.Center)
    )
}

Puntos clave sobre el código

  • Los objetos RoundedPolygon y RoundedPolygonShape se usan para definir y aplicar una forma hexagonal a la imagen.
  • El código usa graphicsLayer para agregar una sombra basada en la elevación a la imagen. Esto crea una sensación de profundidad y separación visual del fondo.
  • El uso de bloques remember optimiza el rendimiento, ya que garantiza que las definiciones de forma y recorte se calculen solo una vez y se recuerden para recomposiciones posteriores de la IU.

Colecciones que contienen esta guía

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

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

Preguntas o comentarios

Visita nuestra página de preguntas frecuentes y consulta las guías rápidas, o bien comunícate con nosotros y comparte tu opinión.