I want to create a half-transparent layer above the camera preview, like this:
I have the camera preview done in my app, all I want is a half-transparent layer over my preview with a cut-out card shape, like in the picture (with rounded corners).
So: fullscreen camera preview, on top of that there is a full screen half-transparent overlay, in which there is a card-shaped hole cut out
How can I do this?
You can use BlendModes to exclude a Rectangle from a transparent layer using
@Composable
private fun TransparentCamLayout() {
Box(
modifier = Modifier
.fillMaxSize()
.drawWithContent {
val canvasWidth = size.width
val canvasHeight = size.height
val width = canvasWidth * .9f
val height = width * 3 / 4f
drawContent()
drawWithLayer {
// Destination
// This is transparent color
drawRect(Color(0x99000000))
// Source
// This is where we extract this rect from transparent
drawRect(
topLeft = Offset((canvasWidth - width) / 2, canvasHeight * .3f),
size = Size(width, height),
color = Color.Transparent,
blendMode = BlendMode.SrcIn
)
}
drawRect(
topLeft = Offset((canvasWidth - width) / 2, canvasHeight * .3f),
size = Size(width, height),
color = Color.White,
style = Stroke(2.dp.toPx())
)
}
) {
Image(
modifier = Modifier.fillMaxSize(),
painter = painterResource(id = R.drawable.landscape5),
contentScale = ContentScale.Crop,
contentDescription = null
)
}
}
/**
* Draw with layer to use [BlendMode]s
*/
private fun DrawScope.drawWithLayer(block: DrawScope.() -> Unit) {
with(drawContext.canvas.nativeCanvas) {
val checkPoint = saveLayer(null, null)
block()
restoreToCount(checkPoint)
}
}
Result
In this tutorial's BlendMode section you can find other usages. As in this answer for custom clipping, building a rating bar and there are many usages limited with your imagination. Blend or PorterDuff modes are very functional for building custom clipping, alpha blending or pixel manipulation.