Android Capturing Images from Camera or Gallery as Bitmaps Kotlin

Hamza Asif
5 min readMar 27, 2021

--

Photo by Eaters Collective on Unsplash

Capturing images using a camera and using it in your Android applications can be tricky at times but the process is quite simple.

So in this story, I will teach you to get images from the gallery or capture images using a camera and then getting those images as bitmaps in our applications.

Note: Learn the use of machine learning and computer vision in Android, Flutter & React Native with our Mobile Machine Learning courses. You can avail discount on the following Android machine-learning courses

  1. Train Object Detection Models for Android — The 2024 Guide
  2. Android & Google Gemini — Build Smart Android Kotlin Apps
  3. Face Recognition and Detection in Android- The 2024 Guide
  4. Android ML — Train Tensorflow Lite Models for Android Apps
  5. ChatGPT & Android — Build Chatbots & Smart Apps for Android
  6. Machine Learning use in Android — The 2024 Guide

So lets’ Start

So firstly create a new Android studio project and select Kotlin as the programming language. For Java click here.

Layout

Now in the activity_main.xml file place an ImageView widget

<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.326"
app:srcCompat="@android:drawable/alert_dark_frame" />

Now inside MainActivity create and initialize this imageview.

class MainActivity : AppCompatActivity() {
var frame: ImageView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
frame = findViewById(R.id.imageView)
}
}

Permissions

As we want to capture images from the camera so we need the camera permission and then to save those images we need storage permission so in the manifest file add these lines

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

Ask for these permissions dynamically inside MainActivity. So add these lines inside the onCreate method of MainActivity.

//TODO ask for permission of camera upon first launch of application
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED || checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_DENIED) {
val permission = arrayOf(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)
requestPermissions(permission, 112)
}
}

Capturing images using the camera

Let’s say when the user will long press on the imageView we want to open the camera and capture the image. Then we want to display that captured image inside our Android application.

So to achieve that set OnLongClickListener on the imageView. So inside onCreate method paste the below code.

//TODO captue image using camera
frame?.setOnLongClickListener(OnLongClickListener {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED || checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_DENIED) {
val permission = arrayOf(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)
requestPermissions(permission, 121)
} else {

}
} else {

}
true
})

So inside this method, we are again checking if the camera and storage permission is granted or not. If the permission is not granted then we are asking for permission again otherwise we are calling a method name openCamera. Inside this method, we have the code to launch the camera. So place this code below onCreate method.

var image_uri: Uri? = null
private val RESULT_LOAD_IMAGE = 123
val IMAGE_CAPTURE_CODE = 654

//TODO opens camera so that user can capture image
private fun openCamera() {
val values = ContentValues()
values.put(MediaStore.Images.Media.TITLE, "New Picture")
values.put(MediaStore.Images.Media.DESCRIPTION, "From the Camera")
image_uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri)
startActivityForResult(cameraIntent, IMAGE_CAPTURE_CODE)
}

Now inside this method, we are launching an intent to open the camera, and once the user will capture the image then the URI of that image will be stored inside the image_uri variable. But to ensure that the user has captured the image we will add the onActivityResult method and check if image was captured or not. So add this method below openCamera method.

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == IMAGE_CAPTURE_CODE && resultCode == Activity.RESULT_OK) {
frame?.setImageURI(image_uri)
}
}

Converting Image into bitmap

Now we have the captured image URI and we are displaying that image inside the image view. But to get the image in a bitmap format place this uriToBitmap method inside MainActivity

//TODO takes URI of the image and returns bitmap
private fun uriToBitmap(selectedFileUri: Uri): Bitmap? {
try {
val parcelFileDescriptor = contentResolver.openFileDescriptor(selectedFileUri, "r")
val fileDescriptor: FileDescriptor = parcelFileDescriptor!!.fileDescriptor
val image = BitmapFactory.decodeFileDescriptor(fileDescriptor)
parcelFileDescriptor.close()
return image
} catch (e: IOException) {
e.printStackTrace()
}
return null
}

Now call this method inside onActivityResult and pass the image uri to get that image in a bitmap format.

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == IMAGE_CAPTURE_CODE && resultCode == Activity.RESULT_OK) {
//imageView.setImageURI(image_uri);
val bitmap = uriToBitmap(image_uri!!)
frame?.setImageBitmap(bitmap)
}
}

And that’s it. Now when you will run this application you will be able to capture an image from the camera and then that image will be displayed inside imageview. As we also converted that image into a bitmap so you can use it for a variety of different purposes.

Choosing Images from a gallery

Let’s say we want to choose the image from the gallery when the user will click on the image view that we placed earlier inside our application layout.

So inside onCreate method set OnClick listener for the image view.

//TODO chose image from gallery
frame?.setOnClickListener(View.OnClickListener {
val galleryIntent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
startActivityForResult(galleryIntent, RESULT_LOAD_IMAGE)
})

Now there you can see when the user will click on the imageview we are launching an intent to open the gallery. And once the user will select an image onActivityResult method will be called and we can get the URI of the selected image inside that method. So add this code inside onActivityResult method

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == IMAGE_CAPTURE_CODE && resultCode == Activity.RESULT_OK) {
frame!!.setImageURI(image_uri)
val bitmap = uriToBitmap(image_uri!!)
frame!!.setImageBitmap(bitmap)
}
if (requestCode == RESULT_LOAD_IMAGE && resultCode == Activity.RESULT_OK && data != null) {
image_uri = data.data
frame!!.setImageURI(image_uri)
}
}

So inside this method, we are getting chosen image Uri and displaying that image inside our image view.

Now when you will run this application you will be able to choose an image from the gallery as well.

Converting Image into bitmap

Now we have the Uri of the image and if you want to get the image as Bitmap So call the uriToBitmap method again. So the code inside onActivityResult will be

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == IMAGE_CAPTURE_CODE && resultCode == Activity.RESULT_OK) {
//imageView.setImageURI(image_uri);
val bitmap = uriToBitmap(image_uri!!)
frame?.setImageBitmap(bitmap)
}
if (requestCode == RESULT_LOAD_IMAGE && resultCode == Activity.RESULT_OK && data != null) {
image_uri = data.data
//imageView.setImageURI(image_uri);
val bitmap = uriToBitmap(image_uri!!)
frame?.setImageBitmap(bitmap)
}
}

And that’s it, now you can run the application and test it. You can also get the application code from Github.

Mobile Machine Learning

Learn the use of machine learning and computer vision in Android, Flutter & React Native with our Mobile Machine Learning courses. You can avail discount on the following Mobile Machine learning courses

Android Machine Learning Courses

Face Recognition in Android — Build Attendance Systems

Train Object Detection Models & build Android Applications

ChatGPT & Android — Build Chatbots & Smart Apps for Android

Android Machine Learning with TensorFlow lite in Java/Kotlin

Android & Regression: Train Prediction ML models for Android

Flutter Machine Learning Courses

Machine Learning for Flutter The Complete 2023 Guide

Face Recognition and Detection in Flutter — The 2024 Guide

Flutter and Linear Regression: Build Prediction Apps Flutter

ChatGPT & Flutter: Build Chatbots & Assistants in Flutter

Train Object Detection and classification models for Flutter

React Native Courses

ChatGPT & React Native — Build Chatbots for Android & IOS

Connect With Me

My Courses: https://www.udemy.com/user/e1c14fb5-1c9b-45ef-a479-bbc543e33254/

My Facebook: https://www.facebook.com/MobileMachineLearning

Youtube Channel: https://www.youtube.com/channel/UCuM6FHbMdYXQCR8syEtnM9Q

--

--

Hamza Asif
Hamza Asif

Written by Hamza Asif

Udemy Instructor, Flutter Dev helping people Integrate ML & AI in Mobile Apps . Visit my courses https://www.udemy.com/user/e1c14fb5-1c9b-45ef-a479-bbc543e33254

No responses yet