Open In App

How to Encrypt and Decrypt Images in Android?

Last Updated : 18 May, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Many times when we are building an android application we have to encrypt the data entered by the user within the android application to maintain the data privacy and security of the application. Along with that we also have to decrypt the data to access it. In this article, we will take a look at How to encrypt and decrypt an image file in our android application. A sample video is given at the end to get an idea about what we are going to do in this article.

Note: This Android article covered in both Java and Kotlin languages. 

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.

Step 2: Add dependency for Glide

Navigate to Gradle Scripts > build.gradle.kts (Module :app) and add the following dependency for image loading

dependencies {
...
implementation("com.github.bumptech.glide:glide:4.16.0")
}


Step 2: Working with the activity_main.xml file

Navigate to app > res > layout > activity_main.xml and add the below code to it. Comments are added in the code to get to know in detail. 

activity_main.xml:

XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    tools:context=".MainActivity">

    <!--image view to display an image-->
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:layout_margin="10dp" />

    <!--button to encrypt the image-->
    <Button
        android:id="@+id/encryptButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:text="Encrypt" />

    <!--button to decrypt the image-->
    <Button
        android:id="@+id/decryptButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:text="Decrypt" />

</LinearLayout>


Step 3: Working with the MainActivity file 

Navigate to app > java > {package-name} > MainActivity.kt file and add the below code to it. Comments are added in the code to get to know in detail. 

MainActivity.java
package org.geeksforgeeks.demo;

import android.content.ContextWrapper;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.bumptech.glide.Glide;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.security.InvalidKeyException;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.spec.SecretKeySpec;

public class MainActivity extends AppCompatActivity {

    private ImageView imageView;
    private Button encBtn;
    private Button decBtn;

    // AES encryption key - must be 16, 24, or 32 bytes in length for AES-128, AES-192, or AES-256 respectively
    private final String secretKey = "MySecretKey12345";

    // Registering an image picker activity to allow the user to select an image from device storage
    private final ActivityResultLauncher<String> imagePickerLauncher =
            registerForActivityResult(new ActivityResultContracts.GetContent(), this::onImagePicked);

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Initialize views
        imageView = findViewById(R.id.imageView);
        encBtn = findViewById(R.id.encryptButton);
        decBtn = findViewById(R.id.decryptButton);

        // Set click listener for encrypt button
        encBtn.setOnClickListener(v -> {
            // Launch image picker to select image for encryption
            imagePickerLauncher.launch("image/*");
        });

        // Set click listener for decrypt button
        decBtn.setOnClickListener(v -> {
            try {
                // Attempt to decrypt and display the image
                decrypt();
            } catch (Exception e) {
                e.printStackTrace();
                Toast.makeText(this, "Decryption failed", Toast.LENGTH_SHORT).show();
            }
        });
    }

    // Callback when an image is picked
    private void onImagePicked(Uri uri) {
        if (uri != null) {
            try {
                // Get input stream of the selected image
                InputStream inputStream = getContentResolver().openInputStream(uri);

                // Encrypt the image using the input stream
                encrypt(inputStream);

                Toast.makeText(this, "Image encrypted.", Toast.LENGTH_SHORT).show();
            } catch (Exception e) {
                e.printStackTrace();
                Toast.makeText(this, "Encryption failed: " + e.getMessage(), Toast.LENGTH_SHORT).show();
            }
        }
    }

    // Returns a directory where encrypted/decrypted images will be stored
    private File getPhotoDirectory() {
        ContextWrapper contextWrapper = new ContextWrapper(this);
        return contextWrapper.getExternalFilesDir(Environment.DIRECTORY_DCIM);
    }

    // Returns file reference for the encrypted image
    private File getEncryptedFile() {
        return new File(getPhotoDirectory(), "encfile.png");
    }

    // Returns file reference for the decrypted image
    private File getDecryptedFile() {
        return new File(getPhotoDirectory(), "decfile.png");
    }

    // Encrypts the image from the input stream using AES encryption
    private void encrypt(InputStream inputStream) throws Exception {
        File encryptedFile = getEncryptedFile();

        // Create AES key specification
        SecretKeySpec sks = new SecretKeySpec(secretKey.getBytes(), "AES");

        // Initialize cipher in encrypt mode
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, sks);

        // Write encrypted data to file
        try (CipherOutputStream cos = new CipherOutputStream(new FileOutputStream(encryptedFile), cipher)) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                cos.write(buffer, 0, bytesRead);
            }
        } finally {
            inputStream.close();
        }
    }

    // Decrypts the previously encrypted image file and displays it in the ImageView
    private void decrypt() throws Exception {
        File encryptedFile = getEncryptedFile();
        File decryptedFile = getDecryptedFile();

        // Create AES key specification
        SecretKeySpec sks = new SecretKeySpec(secretKey.getBytes(), "AES");

        // Initialize cipher in decrypt mode
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, sks);

        // Decrypt data and write it to the decrypted file
        try (
            CipherInputStream cis = new CipherInputStream(new FileInputStream(encryptedFile), cipher);
            FileOutputStream fos = new FileOutputStream(decryptedFile)
        ) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = cis.read(buffer)) != -1) {
                fos.write(buffer, 0, bytesRead);
            }
        }

        // Load and display the decrypted image if it exists
        if (decryptedFile.exists()) {
            Bitmap bitmap = BitmapFactory.decodeFile(decryptedFile.getAbsolutePath());

            // Load bitmap into ImageView using Glide
            Glide.with(this).load(bitmap).into(imageView);

            Toast.makeText(this, "Decryption successful", Toast.LENGTH_SHORT).show();
        }
    }
}
MainActivity.kt
package org.geeksforgeeks.demo

import android.content.ContextWrapper
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.widget.Button
import android.widget.ImageView
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import com.bumptech.glide.Glide
import java.io.*
import java.security.InvalidKeyException
import javax.crypto.Cipher
import javax.crypto.CipherInputStream
import javax.crypto.CipherOutputStream
import javax.crypto.spec.SecretKeySpec

class MainActivity : AppCompatActivity() {
    private lateinit var imageView: ImageView
    private lateinit var encBtn: Button
    private lateinit var decBtn: Button

    // AES encryption key - must be 16, 24, or 32 bytes in length for AES-128, AES-192, or AES-256 respectively
    private val secretKey = "MySecretKey12345"

    // Registering an image picker activity to allow the user to select an image from device storage
    private val imagePickerLauncher = registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
        uri?.let {
            try {
                // Get input stream of the selected image
                val inputStream = contentResolver.openInputStream(it)

                // Encrypt the image using the input stream
                encrypt(inputStream!!)

                Toast.makeText(this, "Image encrypted.", Toast.LENGTH_SHORT).show()
            } catch (e: Exception) {
                e.printStackTrace()
                Toast.makeText(this, "Encryption failed: ${e.message}", Toast.LENGTH_SHORT).show()
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Initialize views
        imageView = findViewById(R.id.imageView)
        encBtn = findViewById(R.id.encryptButton)
        decBtn = findViewById(R.id.decryptButton)

        // Set click listener for encrypt button
        encBtn.setOnClickListener {
            // Launch image picker to select image for encryption
            imagePickerLauncher.launch("image/*")
        }

        // Set click listener for decrypt button
        decBtn.setOnClickListener {
            try {
                // Attempt to decrypt and display the image
                decrypt()
            } catch (e: Exception) {
                e.printStackTrace()
                Toast.makeText(this, "Decryption failed", Toast.LENGTH_SHORT).show()
            }
        }
    }

    // Returns a directory where encrypted/decrypted images will be stored
    private fun getPhotoDirectory(): File? {
        val contextWrapper = ContextWrapper(this)
        return contextWrapper.getExternalFilesDir(Environment.DIRECTORY_DCIM)
    }

    // Returns file reference for the encrypted image
    private fun getEncryptedFile(): File {
        return File(getPhotoDirectory(), "encfile.png")
    }

    // Returns file reference for the decrypted image
    private fun getDecryptedFile(): File {
        return File(getPhotoDirectory(), "decfile.png")
    }

    // Encrypts the image from the input stream using AES encryption
    @Throws(IOException::class, InvalidKeyException::class)
    private fun encrypt(inputStream: InputStream) {
        val encryptedFile = getEncryptedFile()

        // Create AES key specification
        val sks = SecretKeySpec(secretKey.toByteArray(), "AES")

        // Initialize cipher in encrypt mode
        val cipher = Cipher.getInstance("AES").apply {
            init(Cipher.ENCRYPT_MODE, sks)
        }

        // Write encrypted data to file
        CipherOutputStream(FileOutputStream(encryptedFile), cipher).use { cos ->
            inputStream.use { input ->
                input.copyTo(cos)
            }
        }
    }

    // Decrypts the previously encrypted image file and displays it in the ImageView
    @Throws(IOException::class, InvalidKeyException::class)
    private fun decrypt() {
        val encryptedFile = getEncryptedFile()
        val decryptedFile = getDecryptedFile()

        // Create AES key specification
        val sks = SecretKeySpec(secretKey.toByteArray(), "AES")

        // Initialize cipher in decrypt mode
        val cipher = Cipher.getInstance("AES").apply {
            init(Cipher.DECRYPT_MODE, sks)
        }

        // Decrypt data and write it to the decrypted file
        CipherInputStream(FileInputStream(encryptedFile), cipher).use { cis ->
            FileOutputStream(decryptedFile).use { fos ->
                cis.copyTo(fos)
            }
        }

        // Load and display the decrypted image if it exists
        if (decryptedFile.exists()) {
            val bitmap = BitmapFactory.decodeFile(decryptedFile.path)

            // Load bitmap into ImageView using Glide
            Glide.with(this).load(bitmap).into(imageView)

            Toast.makeText(this, "Decryption successful", Toast.LENGTH_SHORT).show()
        }
    }
}


Output:


Next Article
Article Tags :
Practice Tags :

Similar Reads