This code demonstrates how to crop a circular area from an existing image displayed in an ImageView and display the cropped image in another ImageView in an Android application written in Kotlin.
The code utilizes custom extension functions to achieve this functionality. One function retrieves a Bitmap image from the assets folder of the application. The other function performs the core image manipulation - cropping a circular area from the original bitmap.
Breakdown and Summary
The MainActivity.kt
file handles the activity lifecycle and UI interaction. It retrieves a bitmap from the assets folder using the assetsToBitmap
extension function and displays it in the first ImageView.
The cropCircularArea
extension function is the heart of the image manipulation. It takes an optional diameter parameter (defaults to the minimum of width and height) and performs the following steps:
- Creates a new bitmap with the same dimensions and configuration (ARGB_8888) as the original.
- Creates a canvas for drawing on the new bitmap.
- Defines a circular path based on the provided diameter or the minimum dimension of the original image.
- Clips the canvas to the defined circular path.
- Draws the original bitmap onto the canvas.
- Calculates the offset coordinates to extract the desired circular area.
- Creates a final cropped bitmap from the new bitmap using the calculated offsets and diameter as width and height.
Finally, the cropped circular image is displayed in the second ImageView, and a text view displays information about the crop radius.
package com.example.jetpack
import android.content.Context
import android.graphics.*
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
import java.io.IOException
import kotlin.math.min
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// get bitmap from assets folder
val bitmap: Bitmap? = assetsToBitmap("flower9.jpg")
// show bitmap on first image view
bitmap?.apply { imageView.setImageBitmap(this) }
// crop specified size circular area from bitmap
bitmap?.cropCircularArea(700)?.apply {
imageView2.setImageBitmap(this)
textView.text = "Circular image view, crop radius: 350 pixels"
}
}
}
// extension function to crop specified size circular area from bitmap
fun Bitmap.cropCircularArea(
diameter:Int = min(width,height)
):Bitmap?{
val bitmap = Bitmap.createBitmap(
width, // width in pixels
height, // height in pixels
Bitmap.Config.ARGB_8888
)
val canvas = Canvas(bitmap)
// create a circular path
val path = Path()
val length = min(diameter,min(width,height))
val radius = length / 2F // in pixels
path.apply {
addCircle(
width/2f,
height/2f,
radius,
Path.Direction.CCW
)
}
// draw circular bitmap on canvas
canvas.clipPath(path)
canvas.drawBitmap(this,0f,0f,null)
val x = (width - length)/2
val y = (height - length)/2
// return cropped circular bitmap
return Bitmap.createBitmap(
bitmap, // source bitmap
x, // x coordinate of the first pixel in source
y, // y coordinate of the first pixel in source
length, // width
length // height
)
}
// extension function to get bitmap from assets
fun Context.assetsToBitmap(fileName: String): Bitmap?{
return try {
with(assets.open(fileName)){
BitmapFactory.decodeStream(this)
}
} catch (e: IOException) { null }
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#DCDCDC"
tools:context=".MainActivity">
<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="260dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:srcCompat="@tools:sample/avatars" />
<ImageView
android:id="@+id/imageView2"
android:layout_width="0dp"
android:layout_height="260dp"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView"
tools:srcCompat="@tools:sample/avatars" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
tools:text="TextView"
android:fontFamily="sans-serif-condensed-medium"
style="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintEnd_toEndOf="@+id/imageView2"
app:layout_constraintStart_toStartOf="@+id/imageView2"
app:layout_constraintTop_toBottomOf="@+id/imageView2" />
</androidx.constraintlayout.widget.ConstraintLayout>
- android kotlin - Volley string request
- android kotlin - Chip center text
- android kotlin - EditText remove underline while typing
- android kotlin - EditText change cursor color programmatically
- android kotlin - EditText change underline color programmatically
- android kotlin - EditText hide keyboard after enter
- android kotlin - EditText hide keyboard click outside
- android kotlin - EditText enter key listener
- android kotlin - Switch button listener
- android kotlin - Material switch button
- android kotlin - Get raw resource uri
- android kotlin - Create ImageView programmatically
- android kotlin - ImageView rounded corners transparent
- android kotlin - Circular ImageView with border
- android kotlin - Circular ImageView programmatically