Skip to content

Instantly share code, notes, and snippets.

@eluleci
Last active April 6, 2023 05:21
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save eluleci/09663616b15ecea81c39 to your computer and use it in GitHub Desktop.
Save eluleci/09663616b15ecea81c39 to your computer and use it in GitHub Desktop.
Android: Helper for Android for selecting image from gallery, taking a photo with camera and cropping image.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/select_photo_from_gallery"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Select photo from gallery" />
<Button
android:id="@+id/take_picture_with_camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Take picture with camera" />
</LinearLayout>
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.util.Log;
import java.io.File;
import java.io.IOException;
/**
* Class that helps, for Android App, selecting image from gallery, getting image from camera and
* cropping image.
* <p/>
* <p/>
* IMPORTANT: The Activity, that contains this object or that contains the fragment that uses this
* object, must handle the orientation change during taking photo. Either lock the orientation of
* the Activity or handle orientation changes. Otherwise taking photo feature will not work since
* the new instance of this object will be created when device rotates.
*/
public class ImageInputHelper {
public static final int REQUEST_PICTURE_FROM_GALLERY = 23;
public static final int REQUEST_PICTURE_FROM_CAMERA = 24;
public static final int REQUEST_CROP_PICTURE = 25;
private static final String TAG = "ImageInputHelper";
private File tempFileFromSource = null;
private Uri tempUriFromSource = null;
private File tempFileFromCrop = null;
private Uri tempUriFromCrop = null;
/**
* Activity object that will be used while calling startActivityForResult(). Activity then will
* receive the callbacks to its own onActivityResult() and is responsible of calling the
* onActivityResult() of the ImageInputHelper for handling result and being notified.
*/
private Activity mContext;
/**
* Fragment object that will be used while calling startActivityForResult(). Fragment then will
* receive the callbacks to its own onActivityResult() and is responsible of calling the
* onActivityResult() of the ImageInputHelper for handling result and being notified.
*/
private Fragment fragment;
/**
* Listener instance for callbacks on user events. It must be set to be able to use
* the ImageInputHelper object.
*/
private ImageActionListener imageActionListener;
public ImageInputHelper(Activity mContext) {
this.mContext = mContext;
}
public ImageInputHelper(Fragment fragment) {
this.fragment = fragment;
this.mContext = fragment.getActivity();
}
public void setImageActionListener(ImageActionListener imageActionListener) {
this.imageActionListener = imageActionListener;
}
/**
* Handles the result of events that the Activity or Fragment receives on its own
* onActivityResult(). This method must be called inside the onActivityResult()
* of the container Activity or Fragment.
*
* @param requestCode
* @param resultCode
* @param data
*/
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if ((requestCode == REQUEST_PICTURE_FROM_GALLERY) && (resultCode == Activity.RESULT_OK)) {
Log.d(TAG, "Image selected from gallery");
imageActionListener.onImageSelectedFromGallery(data.getData(), tempFileFromSource);
} else if ((requestCode == REQUEST_PICTURE_FROM_CAMERA) && (resultCode == Activity.RESULT_OK)) {
Log.d(TAG, "Image selected from camera");
imageActionListener.onImageTakenFromCamera(tempUriFromSource, tempFileFromSource);
} else if ((requestCode == REQUEST_CROP_PICTURE) && (resultCode == Activity.RESULT_OK)) {
Log.d(TAG, "Image returned from crop");
imageActionListener.onImageCropped(tempUriFromCrop, tempFileFromCrop);
}
}
/**
* Starts an intent for selecting image from gallery. The result is returned to the
* onImageSelectedFromGallery() method of the ImageSelectionListener interface.
*/
public void selectImageFromGallery() {
checkListener();
if (tempFileFromSource == null) {
try {
tempFileFromSource = File.createTempFile("choose", "png", mContext.getExternalCacheDir());
tempUriFromSource = Uri.fromFile(tempFileFromSource);
} catch (IOException e) {
e.printStackTrace();
}
}
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.putExtra(MediaStore.EXTRA_OUTPUT, tempUriFromSource);
if (fragment == null) {
mContext.startActivityForResult(intent, REQUEST_PICTURE_FROM_GALLERY);
} else {
fragment.startActivityForResult(intent, REQUEST_PICTURE_FROM_GALLERY);
}
}
/**
* Starts an intent for taking photo with camera. The result is returned to the
* onImageTakenFromCamera() method of the ImageSelectionListener interface.
*/
public void takePhotoWithCamera() {
checkListener();
if (tempFileFromSource == null) {
try {
tempFileFromSource = File.createTempFile("choose", "png", mContext.getExternalCacheDir());
tempUriFromSource = Uri.fromFile(tempFileFromSource);
} catch (IOException e) {
e.printStackTrace();
}
}
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, tempUriFromSource);
if (fragment == null) {
mContext.startActivityForResult(intent, REQUEST_PICTURE_FROM_CAMERA);
} else {
fragment.startActivityForResult(intent, REQUEST_PICTURE_FROM_CAMERA);
}
}
/**
* Starts an intent for cropping an image that is saved in the uri. The result is
* returned to the onImageCropped() method of the ImageSelectionListener interface.
*
* @param uri uri that contains the data of the image to crop
* @param outputX width of the result image
* @param outputY height of the result image
* @param aspectX horizontal ratio value while cutting the image
* @param aspectY vertical ratio value of while cutting the image
*/
public void requestCropImage(Uri uri, int outputX, int outputY, int aspectX, int aspectY) {
checkListener();
if (tempFileFromCrop == null) {
try {
tempFileFromCrop = File.createTempFile("crop", "png", mContext.getExternalCacheDir());
tempUriFromCrop = Uri.fromFile(tempFileFromCrop);
} catch (IOException e) {
e.printStackTrace();
}
}
// open crop intent when user selects image
final Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("output", tempUriFromCrop);
intent.putExtra("outputX", outputX);
intent.putExtra("outputY", outputY);
intent.putExtra("aspectX", aspectX);
intent.putExtra("aspectY", aspectY);
intent.putExtra("scale", true);
intent.putExtra("noFaceDetection", true);
if (fragment == null) {
mContext.startActivityForResult(intent, REQUEST_CROP_PICTURE);
} else {
fragment.startActivityForResult(intent, REQUEST_CROP_PICTURE);
}
}
private void checkListener() {
if (imageActionListener == null) {
throw new RuntimeException("ImageSelectionListener must be set before calling openGalleryIntent(), openCameraIntent() or requestCropImage().");
}
}
/**
* Listener interface for receiving callbacks from the ImageInputHelper.
*/
public interface ImageActionListener {
void onImageSelectedFromGallery(Uri uri, File imageFile);
void onImageTakenFromCamera(Uri uri, File imageFile);
void onImageCropped(Uri uri, File imageFile);
}
}
public class SelectImageActivity extends ActionBarActivity implements ImageInputHelper.ImageActionListener {
private ImageInputHelper imageInputHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_select_image);
imageInputHelper = new ImageInputHelper(this);
imageInputHelper.setImageActionListener(this);
findViewById(R.id.select_photo_from_gallery).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
imageInputHelper.selectImageFromGallery();
}
});
findViewById(R.id.take_picture_with_camera).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
imageInputHelper.takePhotoWithCamera();
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
imageInputHelper.onActivityResult(requestCode, resultCode, data);
}
@Override
public void onImageSelectedFromGallery(Uri uri, File imageFile) {
// cropping the selected image. crop intent will have aspect ratio 16/9 and result image
// will have size 800x450
imageInputHelper.requestCropImage(uri, 800, 450, 16, 9);
}
@Override
public void onImageTakenFromCamera(Uri uri, File imageFile) {
// cropping the taken photo. crop intent will have aspect ratio 16/9 and result image
// will have size 800x450
imageInputHelper.requestCropImage(uri, 800, 450, 16, 9);
}
@Override
public void onImageCropped(Uri uri, File imageFile) {
try {
// getting bitmap from uri
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
// showing bitmap in image view
((ImageView) findViewById(R.id.image)).setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@aemxn
Copy link

aemxn commented Jul 1, 2016

Thank you for this.

@aemxn
Copy link

aemxn commented Jul 1, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment