Sunday, November 17, 2024
Google search engine
HomeLanguagesJavaHow to Compress Image in Android Before Uploading it to Firebase Storage?

How to Compress Image in Android Before Uploading it to Firebase Storage?

Usually, in an app we make users upload images like profile images or others. But there is a chance that the uploaded image is only for display purposes, that too in a short frame. So, these images do not have to be stored in a high-resolution format. Hence even if the user uploads a high-resolution pic, the image must be compressed before storing it in database storage. This article explains how to build an Android application that can compress the images before uploading them to Firebase Storage.

Step-by-Step Implementation

Step 1: Create a new project

Create a new project in Android Studio. You can refer to How to Create/Start a New Project in Android Studio. Note that select Java as the programming language. 

Step 2: Add the firebase storage dependency in the build.gradle (Module : app) file

Navigate to Gradle Scripts > build.gradle (Module : app) and add the below dependency.

dependencies {
   implementation platform('com.google.firebase:firebase-bom:31.2.0')
   implementation 'com.google.firebase:firebase-storage'
}

After adding the above dependencies we should sync our project.  

Step 3: Working with the activity_main.xml file

Navigate to the app > res > layout > activity_main.xml and add the below code to that file. Below is the code for the activity_main.xml file. There are 3 buttons: one for selecting the image, one for uploading the image without compression, and one for uploading the image with compression. Also, one ImageView is present to display the image.

XML




<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >
  
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="20dp"
        android:orientation="vertical">
  
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="GFG app to demonstrate image compression before uploading to firebase storage"
            android:textColor="@color/GFGgreen"
            android:textSize="20sp"/>
  
        <Button
            android:id="@+id/selectImage"
            android:layout_marginTop="20dp"
            android:layout_marginBottom="10dp"
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Select image" />
  
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
  
            <Button
                android:id="@+id/upload"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:layout_marginRight="5dp"
                android:text="Upload Without Compress" />
  
            <Button
                android:id="@+id/uploadWithCompress"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:layout_marginLeft="5dp"
                android:text="Upload With Compress" />
        </LinearLayout>
  
        <ImageView
            android:id="@+id/imageView"
            android:layout_marginTop="40dp"
            android:layout_gravity="center_horizontal"
            android:layout_width="250dp"
            android:layout_height="250dp"
            tools:srcCompat="@tools:sample/avatars" />
  
    </LinearLayout>
    
</RelativeLayout>


Step 4: Working with the MainActivity.java file

Go to the MainActivity.java file and refer to the following code. Comments are added inside the code to understand the code in more detail.

Java




package com.example.gfggo;
  
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
  
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
  
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
  
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
  
public class MainActivity extends AppCompatActivity {
  
    ImageView displayImage;
    Button selectImage, uploadWithoutCompress, uploadWithCompress;
  
    StorageReference storageRef;
  
    private static final int REQUEST_CODE = 101;
    Uri imageUri;
  
    ProgressDialog mLoadingBar;
  
    Bitmap bmp;
    ByteArrayOutputStream baos;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
  
        displayImage = findViewById(R.id.imageView);
        selectImage = findViewById(R.id.selectImage);
        uploadWithoutCompress = findViewById(R.id.upload);
        uploadWithCompress = findViewById(R.id.uploadWithCompress);
  
        storageRef = FirebaseStorage.getInstance().getReference().child("Images");
  
        selectImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // for getting images
                Intent i = new Intent(Intent.ACTION_PICK,
                                      MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(i, REQUEST_CODE);
            }
        });
  
        uploadWithCompress.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(imageUri!=null){
                    uploadImageWithCompress();
                }
            }
        });
  
        uploadWithoutCompress.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(imageUri!=null){
                    uploadImageWithoutCompress();
                }
            }
        });
  
    }
  
    private void uploadImageWithCompress() {
        mLoadingBar =  new ProgressDialog(MainActivity.this);
        mLoadingBar.setTitle("Uploading Image with Compress");
        mLoadingBar.setCanceledOnTouchOutside(false);
        mLoadingBar.show();
  
        // images are stored with timestamp as their name      
        String timestamp = "" + System.currentTimeMillis();
  
        bmp = null;
        try {
            bmp = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri);
        } catch (IOException e) {
            e.printStackTrace();
        }
        baos = new ByteArrayOutputStream();
  
        // here we can choose quality factor
        // in third parameter(ex. here it is 25)
        bmp.compress(Bitmap.CompressFormat.JPEG, 25, baos);
  
        byte[] fileInBytes = baos.toByteArray();
        storageRef.child(timestamp).putBytes(fileInBytes)
          .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                mLoadingBar.dismiss();
                Toast.makeText(MainActivity.this,"Image uploaded successfully!",
                               Toast.LENGTH_SHORT).show();
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                mLoadingBar.dismiss();
                Toast.makeText(MainActivity.this,"Image upload failed!",
                               Toast.LENGTH_SHORT).show();
            }
        });
    }
  
    private void uploadImageWithoutCompress() {
        mLoadingBar =  new ProgressDialog(MainActivity.this);
        mLoadingBar.setTitle("Uploading Image without Compress");
        mLoadingBar.setCanceledOnTouchOutside(false);
        mLoadingBar.show();
  
        final String timestamp = "" + System.currentTimeMillis();
  
        storageRef.child(timestamp).putFile(imageUri)
          .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                mLoadingBar.dismiss();
                Toast.makeText(MainActivity.this,"Image uploaded successfully!",
                               Toast.LENGTH_SHORT).show();
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                mLoadingBar.dismiss();
                Toast.makeText(MainActivity.this,"Image upload failed!",
                               Toast.LENGTH_SHORT).show();
            }
        });
    }
  
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode==REQUEST_CODE && resultCode==RESULT_OK && data!=null){
            imageUri = data.getData();
            displayImage.setImageURI(imageUri);
        }
    }
}


Output:

Main Activity

Main Activity having buttons to select and to upload image with or without compress

Main Activity having buttons to select and to upload image with or without compress

After selecting an image from the gallery 

Main Activity after the user selects an image

Main Activity after the user selects an image

Firebase storage console 

Th first image is without compressed and the second image stored is compressed

Th first image is without compressed and the second image stored is compressed

We can clearly observe in the firebase console that the same image which has been compressed takes less space to store.

RELATED ARTICLES

Most Popular

Recent Comments