Last active
January 20, 2022 11:14
-
-
Save ArthurHub/8a8530dd688df409fb20 to your computer and use it in GitHub Desktop.
Android Crop Camera Image
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<manifest package="com.example.arthu.testandroidcropper" | |
xmlns:android="http://schemas.android.com/apk/res/android"> | |
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> | |
<application | |
android:allowBackup="true" | |
android:icon="@mipmap/ic_launcher" | |
android:label="@string/app_name" | |
android:supportsRtl="true" | |
android:theme="@style/AppTheme"> | |
<activity android:name=".MainActivity"> | |
<intent-filter> | |
<action android:name="android.intent.action.MAIN"/> | |
<category android:name="android.intent.category.LAUNCHER"/> | |
</intent-filter> | |
</activity> | |
</application> | |
</manifest> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
apply plugin: 'com.android.application' | |
android { | |
compileSdkVersion 23 | |
buildToolsVersion "23.0.2" | |
defaultConfig { | |
applicationId "com.theartofdev.cropcameraimage" | |
minSdkVersion 15 | |
targetSdkVersion 23 | |
versionCode 1 | |
versionName "1.0" | |
} | |
buildTypes { | |
release { | |
minifyEnabled false | |
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' | |
} | |
} | |
} | |
dependencies { | |
compile 'com.theartofdev.edmodo:android-image-cropper:1.1.+' | |
compile 'com.android.support:appcompat-v7:23.1.1' | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:app="http://schemas.android.com/apk/res-auto" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:orientation="vertical"> | |
<Button | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:padding="@dimen/activity_horizontal_margin" | |
android:text="Load Image" | |
android:onClick="onLoadImageClick"/> | |
<com.theartofdev.edmodo.cropper.CropImageView | |
android:id="@+id/CropImageView" | |
android:layout_width="match_parent" | |
android:layout_height="0dp" | |
android:layout_weight="1" | |
app:scaleType="fitCenter"/> | |
<Button | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:padding="@dimen/activity_horizontal_margin" | |
android:text="Crop Image" | |
android:onClick="onCropImageClick"/> | |
</LinearLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.theartofdev.cropcameraimage; | |
import android.Manifest; | |
import android.app.Activity; | |
import android.content.ComponentName; | |
import android.content.ContentResolver; | |
import android.content.Intent; | |
import android.content.pm.PackageManager; | |
import android.content.pm.ResolveInfo; | |
import android.graphics.Bitmap; | |
import android.net.Uri; | |
import android.os.Build; | |
import android.os.Bundle; | |
import android.os.Parcelable; | |
import android.provider.MediaStore; | |
import android.system.ErrnoException; | |
import android.support.v7.app.ActionBarActivity; | |
import android.view.View; | |
import com.theartofdev.edmodo.cropper.CropImageView; | |
import java.io.File; | |
import java.io.FileNotFoundException; | |
import java.io.InputStream; | |
import java.util.ArrayList; | |
import java.util.List; | |
public class MainActivity extends ActionBarActivity { | |
private CropImageView mCropImageView; | |
private Uri mCropImageUri; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
mCropImageView = (CropImageView) findViewById(R.id.CropImageView); | |
} | |
/** | |
* On load image button click, start pick image chooser activity. | |
*/ | |
public void onLoadImageClick(View view) { | |
startActivityForResult(getPickImageChooserIntent(), 200); | |
} | |
/** | |
* Crop the image and set it back to the cropping view. | |
*/ | |
public void onCropImageClick(View view) { | |
Bitmap cropped = mCropImageView.getCroppedImage(500, 500); | |
if (cropped != null) | |
mCropImageView.setImageBitmap(cropped); | |
} | |
@Override | |
protected void onActivityResult(int requestCode, int resultCode, Intent data) { | |
if (resultCode == Activity.RESULT_OK) { | |
Uri imageUri = getPickImageResultUri(data); | |
// For API >= 23 we need to check specifically that we have permissions to read external storage, | |
// but we don't know if we need to for the URI so the simplest is to try open the stream and see if we get error. | |
boolean requirePermissions = false; | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && | |
checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED && | |
isUriRequiresPermissions(imageUri)) { | |
// request permissions and handle the result in onRequestPermissionsResult() | |
requirePermissions = true; | |
mCropImageUri = imageUri; | |
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 0); | |
} | |
if (!requirePermissions) { | |
mCropImageView.setImageUriAsync(imageUri); | |
} | |
} | |
} | |
@Override | |
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { | |
if (mCropImageUri != null && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { | |
mCropImageView.setImageUriAsync(mCropImageUri); | |
} else { | |
Toast.makeText(this, "Required permissions are not granted", Toast.LENGTH_LONG).show(); | |
} | |
} | |
/** | |
* Create a chooser intent to select the source to get image from.<br/> | |
* The source can be camera's (ACTION_IMAGE_CAPTURE) or gallery's (ACTION_GET_CONTENT).<br/> | |
* All possible sources are added to the intent chooser. | |
*/ | |
public Intent getPickImageChooserIntent() { | |
// Determine Uri of camera image to save. | |
Uri outputFileUri = getCaptureImageOutputUri(); | |
List<Intent> allIntents = new ArrayList<>(); | |
PackageManager packageManager = getPackageManager(); | |
// collect all camera intents | |
Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); | |
List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0); | |
for (ResolveInfo res : listCam) { | |
Intent intent = new Intent(captureIntent); | |
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name)); | |
intent.setPackage(res.activityInfo.packageName); | |
if (outputFileUri != null) { | |
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri); | |
} | |
allIntents.add(intent); | |
} | |
// collect all gallery intents | |
Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT); | |
galleryIntent.setType("image/*"); | |
List<ResolveInfo> listGallery = packageManager.queryIntentActivities(galleryIntent, 0); | |
for (ResolveInfo res : listGallery) { | |
Intent intent = new Intent(galleryIntent); | |
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name)); | |
intent.setPackage(res.activityInfo.packageName); | |
allIntents.add(intent); | |
} | |
// the main intent is the last in the list (fucking android) so pickup the useless one | |
Intent mainIntent = allIntents.get(allIntents.size() - 1); | |
for (Intent intent : allIntents) { | |
if (intent.getComponent().getClassName().equals("com.android.documentsui.DocumentsActivity")) { | |
mainIntent = intent; | |
break; | |
} | |
} | |
allIntents.remove(mainIntent); | |
// Create a chooser from the main intent | |
Intent chooserIntent = Intent.createChooser(mainIntent, "Select source"); | |
// Add all other intents | |
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, allIntents.toArray(new Parcelable[allIntents.size()])); | |
return chooserIntent; | |
} | |
/** | |
* Get URI to image received from capture by camera. | |
*/ | |
private Uri getCaptureImageOutputUri() { | |
Uri outputFileUri = null; | |
File getImage = getExternalCacheDir(); | |
if (getImage != null) { | |
outputFileUri = Uri.fromFile(new File(getImage.getPath(), "pickImageResult.jpeg")); | |
} | |
return outputFileUri; | |
} | |
/** | |
* Get the URI of the selected image from {@link #getPickImageChooserIntent()}.<br/> | |
* Will return the correct URI for camera and gallery image. | |
* | |
* @param data the returned data of the activity result | |
*/ | |
public Uri getPickImageResultUri(Intent data) { | |
boolean isCamera = true; | |
if (data != null && data.getData() != null) { | |
String action = data.getAction(); | |
isCamera = action != null && action.equals(MediaStore.ACTION_IMAGE_CAPTURE); | |
} | |
return isCamera ? getCaptureImageOutputUri() : data.getData(); | |
} | |
/** | |
* Test if we can open the given Android URI to test if permission required error is thrown.<br> | |
*/ | |
public boolean isUriRequiresPermissions(Uri uri) { | |
try { | |
ContentResolver resolver = getContentResolver(); | |
InputStream stream = resolver.openInputStream(uri); | |
stream.close(); | |
return false; | |
} catch (FileNotFoundException e) { | |
if (e.getCause() instanceof ErrnoException) { | |
return true; | |
} | |
} catch (Exception e) { | |
} | |
return false; | |
} | |
} |
IMPORTANT If the app doesn't have permission to use the camera then trying to open any camera app will cancel the startActivityForResult() and return onActivityResult(int requestCode, 0, null)
(Android 7.1.1)
If you want to do less work, instead of copy-pasting this code, check out https://github.com/jkwiecien/EasyImage
hello ArthurHub
your code keeps on croping the image repeatedly I just want crop once and save the image to gallery
can you please help me
thanks in advance
guys check this out for refrence https://github.com/chiragmak10/Cropping-Image-using-android-image-cropper-
chiragmak, can you add the support for camera as well?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
it's no longer
scaleType
. Instead it'scropScaleType