Skip to content

WebNinjaDeveloper.com

Programming Tutorials




Menu
  • Home
  • Youtube Channel
  • Official Blog
  • Nearby Places Finder
  • Direction Route Finder
  • Distance & Time Calculator
Menu

Android Java Project to Crop,Scale & Rotate Images Selected From Gallery and Save it inside SD Card

Posted on March 2, 2023

 

Welcome folks today in this blog post we will be building an android app where we will be cropping,scaling and rotating selected images from gallery and then we need to display the result inside the imageView widget and also saving the image inside the sd card in java. All the full source code of the application is shown below.

 

 

Get Started

 

 

In order to get started you need to make a new android project inside the android studio and then you will see the below directory structure as shown below at the end of the project.

 

 

 

 

 

Now we need to edit the AndroidManifest.xml file you need to include the internet permission so that we can fetch external data from the jsonplaceholder api.

 

 

AndroidManifest.xml

 

 

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

 

 

Adding External Dependencies

 

 

Now guys we need to add the below lines inside the dependencies block of the build.gradle file as shown below

 

 

 

1
2
3
dependencies {
    implementation 'com.github.krokyze:ucropnedit:2.2.6-2'
}

 

 

Now after adding the above lines you need to press the sync button and after that android studio will install these dependencies automatically in the background.

 

 

Now we need to edit the activity_main.xml layout file where we have the imageView widget where we have the image drawable as shown below.

 

 

activity_main.xml

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
 
    <ImageView
        android:id="@+id/btn_pick_image"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:layout_margin="16dp"
        android:src="@mipmap/ic_launcher_round"/>
 
 
</LinearLayout>

 

 

 

And now we need to edit the MainActivity.java file and copy paste the following code

 

 

MainActivity.java

 

 

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
 
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
 
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
 
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
 
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
 
 
public class MainActivity extends AppCompatActivity {
 
    ImageView iv_pick_image;
 
    ActivityResultLauncher<String> mGetContent;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        iv_pick_image = findViewById(R.id.btn_pick_image);
 
 
        iv_pick_image.setOnClickListener(new View.OnClickListener() {
 
            @Override
            public void onClick(View v) {
                mGetContent.launch("image/*");
            }
        });
 
        mGetContent = registerForActivityResult(new ActivityResultContracts.GetContent(), new ActivityResultCallback<Uri>() {
            @Override
            public void onActivityResult(Uri result) {
                Intent intent = new Intent(MainActivity.this, CropperActivity.class);
                intent.putExtra("DATA",result.toString());
                startActivityForResult(intent,101);
            }
        });
    }
 
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
 
        if(resultCode == -1 && requestCode == 101){
            String result = data.getStringExtra("RESULT");
            Log.d("s",result);
            Uri resultUri = null;
            if(result != null){
                resultUri = Uri.parse(result);
            }
 
            iv_pick_image.setImageURI(resultUri);
            Log.d("f", String.valueOf(resultUri));
 
            ParcelFileDescriptor parcelFileDescriptor = null;
            try {
                parcelFileDescriptor = getContentResolver().openFileDescriptor(resultUri, "r");
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            }
            FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
            Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
            try {
                parcelFileDescriptor.close();
 
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
 
        }
    }
}

 

 

As you can see in the above java code we are binding the onClick listener on the ImageView widget and after that we are selecting the image from the gallery and then we are cropping the image using the controls and then we are redirecting or showing the cropped image inside the imageView widget.

 

But before running the app we need to add the crop activity inside the AndroidManifest.xml file as shown below

 

 

AndroidManifest.xml

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 
 
    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/Theme.SampleApp"
        tools:targetApi="31">
        <activity
            android:name=".CropperActivity"
            android:exported="false" />
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.yalantis.ucrop.UCropActivity"
            android:screenOrientation="portrait"
            android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
    </application>
 
</manifest>

 

 

And now we need to create the CropperActivity class where we will be redirecting the users to crop the image as shown below

 

 

CropperActivity.java

 

 

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
 
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
 
import com.yalantis.ucrop.UCrop;
 
import java.io.File;
import java.util.UUID;
 
public class CropperActivity extends AppCompatActivity {
 
    String result;
    Uri fileUri;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cropper);
 
        readIntent();
 
        String dest_uri = new StringBuilder(UUID.randomUUID().toString()).append(".jpg").toString();
 
        UCrop.Options options = new UCrop.Options();
 
 
        UCrop.of(fileUri,Uri.fromFile(new File(getCacheDir(),dest_uri)))
                .withOptions(options)
                .withAspectRatio(0,0)
                .useSourceImageAspectRatio()
                .withMaxResultSize(2000,2000)
                .start(CropperActivity.this);
 
    }
 
    private void readIntent(){
        Intent intent = getIntent();
        if(intent.getExtras() != null){
            result = intent.getStringExtra("DATA");
            fileUri = Uri.parse(result);
        }
    }
 
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
 
        if(resultCode == RESULT_OK && requestCode == UCrop.REQUEST_CROP){
            final Uri resultUri = UCrop.getOutput(data);
            Intent returnIntent = new Intent();
            returnIntent.putExtra("RESULT",resultUri + "");
            setResult(-1,returnIntent);
            finish();
        }else if(resultCode == UCrop.RESULT_ERROR){
            final Throwable cropError = UCrop.getError(data);
        }
    }
}

 

 

As you can see we are importing the UCrop library and then we are using the data or image selected by the user using Intents and then we are cropping the image and passing the data uri of the cropped image back to the MainActivity using the Intent class. For this we are using the putExtra() method and inside this we are passing the uri of the image.

 

 

 

 

Saving Cropped Image in Gallery or SD Card

 

 

Now we can add the code inside the MainActivity.java file to save the cropped image inside the sd card as shown below

 

 

MainActivity.java

 

 

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package com.example.sampleapp;
 
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
 
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
 
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
 
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
 
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
 
 
public class MainActivity extends AppCompatActivity {
 
    ImageView iv_pick_image;
 
    ActivityResultLauncher<String> mGetContent;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        iv_pick_image = findViewById(R.id.btn_pick_image);
 
 
        iv_pick_image.setOnClickListener(new View.OnClickListener() {
 
            @Override
            public void onClick(View v) {
                mGetContent.launch("image/*");
            }
        });
 
        mGetContent = registerForActivityResult(new ActivityResultContracts.GetContent(), new ActivityResultCallback<Uri>() {
            @Override
            public void onActivityResult(Uri result) {
                Intent intent = new Intent(MainActivity.this, CropperActivity.class);
                intent.putExtra("DATA",result.toString());
                startActivityForResult(intent,101);
            }
        });
    }
 
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
 
        if(resultCode == -1 && requestCode == 101){
            String result = data.getStringExtra("RESULT");
            Log.d("s",result);
            Uri resultUri = null;
            if(result != null){
                resultUri = Uri.parse(result);
            }
 
            iv_pick_image.setImageURI(resultUri);
            Log.d("f", String.valueOf(resultUri));
 
            ParcelFileDescriptor parcelFileDescriptor = null;
            try {
                parcelFileDescriptor = getContentResolver().openFileDescriptor(resultUri, "r");
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            }
            FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
            Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
            try {
                parcelFileDescriptor.close();
 
 
                saveImageToGallery(this,image);
 
 
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
 
        }
    }
 
    public void saveImageToGallery(Context context, Bitmap bitmap) {
        // Create a new directory inside the gallery folder
        String galleryPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath();
        File imgDir = new File(galleryPath + "/picsfolder");
        if (!imgDir.exists()) {
            imgDir.mkdir();
        }
 
        // Create a unique filename for the image
        String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
        String filename = "IMG_" + timestamp + ".jpg";
        File imageFile = new File(imgDir, filename);
 
        try {
            // Save the bitmap to the file
            FileOutputStream fos = new FileOutputStream(imageFile);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);
            fos.flush();
            fos.close();
 
            // Add the image to the gallery
            MediaStore.Images.Media.insertImage(context.getContentResolver(), imageFile.getAbsolutePath(), filename, null);
 
            // Get the URI for the saved image
            String uriString = MediaStore.Images.Media.getContentUri("external").toString() + "/" + imageFile.getName();
            Uri imageUri = Uri.parse(uriString);
 
            // Notify the gallery that a new image has been added
            Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
            intent.setData(imageUri);
            context.sendBroadcast(intent);
 
            // Show a toast message with the image URI
            Toast.makeText(context, "Image saved: " + uriString, Toast.LENGTH_SHORT).show();
        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(context, "Failed to save image", Toast.LENGTH_SHORT).show();
        }
    }
}

 

 

As you can see in the saveImageToGallery() method we are using the MediaStore class to interact with the gallery to create a folder inside the Pictures directory in gallery. And then we are creating the random filename and saving it and then showing the toast message when the file is saved.

 

Recent Posts

  • Android Java Project to Crop,Scale & Rotate Images Selected From Gallery and Save it inside SD Card
  • Android Kotlin Project to Load Image From URL into ImageView Widget
  • Android Java Project to Make HTTP Call to JSONPlaceholder API and Display Data in RecyclerView Using GSON & Volley Library
  • Android Java Project to Download Youtube Video Thumbnail From URL & Save it inside SD Card
  • Android Java Project to Embed Google Maps & Add Markers Using Maps SDK
  • Angular
  • Bunjs
  • C#
  • Deno
  • django
  • Electronjs
  • java
  • javascript
  • Koajs
  • kotlin
  • Laravel
  • meteorjs
  • Nestjs
  • Nextjs
  • Nodejs
  • PHP
  • Python
  • React
  • ReactNative
  • Svelte
  • Tutorials
  • Vuejs




©2023 WebNinjaDeveloper.com | Design: Newspaperly WordPress Theme