Skip to content
This site is a preview of pull request #1363.

Capture a map image

An MapSnapshotter renders an independent, non-UI map to an ImageBitmap. createMapState and createSnapshotter both accept a BaseStyle and a content block. Pass the same base style and the same content function to capture the displayed map’s declared content. Copy its current camera position into the capture request.

Create and close the snapshotter in a coroutine. MapSnapshotter.capture suspends until the image is ready:

App.kt
suspend fun captureCurrentMap(
runtime: MapRuntime,
mapState: MapState,
content: @Composable @MaplibreComposable () -> Unit,
density: Density,
layoutDirection: LayoutDirection,
): ImageBitmap {
val snapshotter =
runtime.createSnapshotter(
baseStyle = mapState.style.baseStyle,
content = content,
)
return try {
snapshotter.capture(
MapSnapshotRequest(
width = 640,
height = 360,
cameraPosition = mapState.cameraPosition,
density = density.density,
fontScale = density.fontScale,
layoutDirection = layoutDirection,
)
)
} finally {
withContext(NonCancellable) {
snapshotter.close()
snapshotter.awaitClosed()
}
}
}

The request width and height are logical pixels. Its density scales the output bitmap and evaluates Dp values in the content block. Pass LocalDensity.current and LocalLayoutDirection.current from the calling composable to match the displayed map. The content block reads the viewport of the request through LocalViewport.

For repeated captures, keep one snapshotter and call capture again with a new request. Calls that overlap execute in submission order. Close the snapshotter when its owner leaves the composition, then call MapSnapshotter.awaitClosed from a non-cancellable cleanup block.