Converting Composables To Bitmap Using Canvas
When developing photo editing apps or quote maker-like apps you need to export the image with text, colours, shapes, etc. to the final output. It was very easy when using XML but, now Jetpack Compose is in the market. You need a way to export the composable to Bitmap.
In this post, we will see how you can do it with a Modifier
easily with the complete example.
Steps to Export Bitmaps
- Use
drawIntoCanvas
Method and delegate toandroid.graphics.Picture
class. - Then save
Picture
to Local Storage.
First Thing First Add The Latest Release Of Compose Dependency1.6.0-alpha03
implementation “androidx.compose.ui:ui:1.6.0-alpha03” |
Why drawWithCache Modifier?
Modifier.drawWithCache
keeps the objects that are created inside of it cached. The objects are cached as long as the size of the drawing area is the same, or any state objects that are read have not changed. This modifier is useful for improving the performance of drawing calls as it avoids the need to reallocate objects (such as: Brush, Shader, Path
etc.) that are created on the draw.
Alternatively, you could also cache objects using remember
, outside of the modifier. However, this is not always possible as you don’t always have access to the composition. It can be more performant to use drawWithCache
if the objects are only used for drawing.
val picture = remember { Picture() }
Column(
modifier = Modifier
.padding(padding)
.fillMaxSize()
.drawWithCache {
// Example that shows how to redirect rendering to an Android Picture and then
// draw the picture into the original destination
val width = this.size.width.toInt()
val height = this.size.height.toInt()
onDrawWithContent {
val pictureCanvas =
androidx.compose.ui.graphics.Canvas(
picture.beginRecording(
width,
height
)
)
draw(this, this.layoutDirection, pictureCanvas, this.size) {
this@onDrawWithContent.drawContent()
}
picture.endRecording()
drawIntoCanvas { canvas -> canvas.nativeCanvas.drawPicture(picture) }
}
}
) {
ScreenContentToCapture()
}
After drawing the cache into Picture
. You can use Picture
an object to get the bitmap and export them to Local storage.
Saving the Image
We will use Picture Object to capture the image and draw it into canvas and save that Bitmap to Local storage using the FileWriter.
private fun createBitmapFromPicture(picture: Picture): Bitmap {
val bitmap = Bitmap.createBitmap(
picture.width,
picture.height,
Bitmap.Config.ARGB_8888
)
val canvas = android.graphics.Canvas(bitmap)
canvas.drawColor(android.graphics.Color.WHITE)
canvas.drawPicture(picture)
return bitmap
}
private suspend fun Bitmap.saveToDisk(context: Context): Uri {
val file = File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"screenshot-${System.currentTimeMillis()}.png"
)
file.writeBitmap(this, Bitmap.CompressFormat.PNG, 100)
return scanFilePath(context, file.path) ?: throw Exception("File could not be saved")
}
private fun File.writeBitmap(bitmap: Bitmap, format: Bitmap.CompressFormat, quality: Int) {
outputStream().use { out ->
bitmap.compress(format, quality, out)
out.flush()
}
}
Done !. We have exported the Bitmap to SDCard.
🍴Check out the complete code on my GitHub Gist. ✍️ Hope this project really helps you.
Hope you enjoy coding Jetpack Compose 😁. Don’t forget to share 📨 and clap 👏.
Any Suggestions are welcome. If you need any help or have questions for Code Contact Me. You can follow me on LinkedIn, StackOverflow and Twitter For More Updates 🔔
Happy Compose !! 🚀