Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

Circular Crop an Image and Save it to the File in Android

  • Last Updated : 05 Aug, 2021

There are multiple applications available in the market that help in dealing with image processing, while most of them fail to produce very basic operations. Cropping is a simple application when one could resize an image by cutting it down. This task becomes complex when it comes to free-hand or shape cropping, meaning cropping the image in the desired shape.

In this article, we will show you how you create an application to crop an image in a circular manner and store it in the local device. No external library or service is used to generate this application.

Step by Step Implementation

Step 1: Create a New Project in Android Studio

To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. We demonstrated the application in Kotlin, so make sure you select Kotlin as the primary language while creating a New Project.

Step 2: Add an ImageView and two Buttons in the activity_main.xml or the layout file


<?xml version="1.0" encoding="utf-8"?>
      <!-- Image will be loaded here -->
        android:layout_centerInParent="true" />
      <!-- Button to perform Cropping -->
        android:text="Crop" />
      <!-- Button to save the image in ImageView -->
        android:text="Save" />

Step 3: Add the desired image in the res > drawable folder

While adding, give it the desired name. For our reference, this image is “image.png” which is downloaded from the Internet and copied directly into the drawable folder.

Step 4: Write the following code for MainActivity.kt

There are two functions inside this code:

  1. getCircularBitmap(Bitmap) : To crop the image
  2. saveMediaToStorage(Bitmap) : To save the image. Refer How to Capture Screenshot of a View and Save it to Gallery in Android?

Refer to the comments for better understanding.


import android.content.ContentValues
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import android.widget.Button
import android.widget.ImageView
import android.widget.Toast
import androidx.annotation.RequiresApi
import java.lang.Integer.min
class MainActivity : AppCompatActivity() {
    // Declaring the UI elements from the layout file
    private lateinit var buttonCrop: Button
    private lateinit var buttonSave: Button
    private lateinit var imageView: ImageView
    // Declaring the Bitmap
    private lateinit var bitmap: Bitmap
    override fun onCreate(savedInstanceState: Bundle?) {
        // Initializing the UI elements
        imageView = findViewById(
        buttonCrop = findViewById(
        buttonSave = findViewById(
        // Declaring resource address ( type integer)
        val bitmapResourceID: Int = R.drawable.image
        // Setting the ImageView with the Image
        imageView.setImageBitmap(BitmapFactory.decodeResource(resources, bitmapResourceID))
        bitmap = BitmapFactory.decodeResource(resources, bitmapResourceID)
        // When Crop button is clicked
        buttonCrop.setOnClickListener {
              // runs a custom function on the original image
            bitmap = getCircularBitmap(bitmap)
            // Sets the ImageView with the editted/cropped Image
        // When Save button is clicked
        buttonSave.setOnClickListener {
             // Save whatever the bitmap is (edited/uneditted) into the device.
    // Function to crop the image in a circle
    private fun getCircularBitmap(srcBitmap: Bitmap?): Bitmap {
        // Select whichever of width or height is minimum
        val squareBitmapWidth = min(srcBitmap!!.width, srcBitmap.height)
        // Generate a bitmap with the above value as dimensions
        val dstBitmap = Bitmap.createBitmap(
        // Initializing a Canvas with the above generated bitmap
        val canvas = Canvas(dstBitmap)
        // initializing Paint
        val paint = Paint()
        paint.isAntiAlias = true
        // Generate a square (rectangle with all sides same)
        val rect = Rect(0, 0, squareBitmapWidth, squareBitmapWidth)
        val rectF = RectF(rect)
        // Operations to draw a circle
        canvas.drawOval(rectF, paint)
        paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
        val left = ((squareBitmapWidth - srcBitmap.width) / 2).toFloat()
        val top = ((squareBitmapWidth - srcBitmap.height) / 2).toFloat()
        canvas.drawBitmap(srcBitmap, left, top, paint)
        // Return the bitmap
        return dstBitmap
    // Function to save an Image
    private fun saveMediaToStorage(bitmap: Bitmap) {
        val filename = "${System.currentTimeMillis()}.jpg"
        var fos: OutputStream? = null
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            this.contentResolver?.also { resolver ->
                val contentValues = ContentValues().apply {
                    put(MediaStore.MediaColumns.DISPLAY_NAME, filename)
                    put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg")
                    put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)
                val imageUri: Uri? = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
                fos = imageUri?.let { resolver.openOutputStream(it) }
        } else {
            val imagesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
            val image = File(imagesDir, filename)
            fos = FileOutputStream(image)
        fos?.use {
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, it)
            Toast.makeText(this , "Captured View and saved to Gallery" , Toast.LENGTH_SHORT).show()

Step 4: Add Storage permission in the AndroidManifest.xml file

This permission is needed to store the image in the device.


    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />


My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!