<br />

You can fit an image to a clipped shape, and draw shadows around the perimeter of the shape to impart a three-dimensional feel. This technique is useful for creating designs such as avatars and product thumbnails, or displaying logos with custom shapes.

To display an image clipped to a shape, you must do the following:

- Create the shape.
- Clip the image to the shape.

## Results

![Dog in hexagon with shadow applied around the edges](https://developer.android.com/static/develop/ui/compose/images/graphics/shapes/clip_with_shadow.png)**Figure 1.**Custom shape applied as clip.

## Version compatibility

This implementation requires that your project minSDK be set to API level 21 or higher.

### Dependencies

### Kotlin

<br />

```kotlin
  implementation(platform("androidx.compose:compose-bom:2025.10.01"))
  implementation("androidx.graphics:graphics-shapes:1.0.0-alpha05")
  
```

<br />

### Groovy

<br />

```groovy
  implementation platform('androidx.compose:compose-bom:2025.10.01')
  implementation 'androidx.graphics:graphics-shapes:1.0.0-alpha05'
  
```

<br />

## Create a shape

The following code creates a custom shape that can dynamically draw and render a rounded polygon:

<br />

```kotlin
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)
    }
}https://github.com/android/snippets/blob/95aeebd507b29719a9e7d5a839f101bbbe42ea72/compose/snippets/src/main/java/com/example/compose/snippets/graphics/ShapesSnippets.kt#L353-L375
```

<br />

### Key points about the code

- `RoundedPolygon.getBounds()`defines an extension function on the[`RoundedPolygon`](https://developer.android.com/reference/kotlin/androidx/graphics/shapes/RoundedPolygon)class to calculate its bounds.
- The`RoundedPolygonShape`class implements the[`Shape`](https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Shape)interface, allowing you to define a custom shape (a rounded polygon) in Jetpack Compose.
- The shape uses a[`Matrix`](https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Matrix)to manage scaling and translation operations for flexible rendering.
- The`createOutline()`function takes a`RoundedPolygon`object, scales and translates it to fit within a given size, and returns an[`Outline`](https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Outline)object that describes the final shape to be drawn.

## Clip the image to a shape

The following code crops the image to a hexagon, and adds a subtle drop shadow to provide a sense of depth:

<br />

```kotlin
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)
    )
}https://github.com/android/snippets/blob/95aeebd507b29719a9e7d5a839f101bbbe42ea72/compose/snippets/src/main/java/com/example/compose/snippets/graphics/ShapesSnippets.kt#L382-L402
```

<br />

### Key points about the code

- The`RoundedPolygon`and`RoundedPolygonShape`objects are used to define and apply a hexagonal shape to the image.
- The code uses[`graphicsLayer`](https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/package-summary#(androidx.compose.ui.Modifier).graphicsLayer(kotlin.Function1))to add an elevation-based shadow to the image. This creates a sense of depth and visual separation from the background.
- The use of[`remember`](https://developer.android.com/reference/kotlin/androidx/compose/runtime/package-summary#remember(kotlin.Function0))blocks optimizes performance by ensuring that the shape and clipping definitions are calculated only once and remembered for later recompositions of the UI.

## Collections that contain this guide

This guide is part of these curated Quick Guide collections that cover broader Android development goals:  
![](https://developer.android.com/static/images/quick-guides/collection-illustration.png)  
![](https://developer.android.com/static/images/picto-icons/collection.svg)  

### Display images

Discover techniques for using bright, engaging visuals to give your Android app a beautiful look and feel.  
[Quick guide collection](https://developer.android.com/develop/ui/compose/quick-guides/collections/display-images)
![](https://developer.android.com/static/images/picto-icons/help.svg)  

## Have questions or feedback

Go to our frequently asked questions page and learn about quick guides or reach out and let us know your thoughts.  
[Go to FAQ](https://developer.android.com/quick-guides/faq)[Leave feedback](https://issuetracker.google.com/issues/new?component=1573691&template=1993320)