Android photo image selection and image Cropping
Recently, I have extracted a common module from my previous projects. Here, it is necessary to record that it is necessary to obtain and crop images on android. How about this? This function is very common. If you open an App at will, as long as it has the registration function, it will have the function of setting the character avatar, especially in content-based apps, how are these functions implemented? Today, we will record it here to prevent future projects from being used, so we can use it directly.
1. Get images by taking photos or using an album (cropping is not required)
This method is used to obtain images. Because the image cropping function is not set, OOM may occur because the image is too large. However, it is necessary to explain this method, there are two ways to obtain images: one is to call the System camera to take an image in real time, the other is to open the existing image library on the device, and select a picture in the Image Library. The implementation of these two methods is a truth, nothing more than calling the system through Intent. The following is the source code. The first is the Activity for selecting images. This Activity is set to the Dialog mode and needs to be set.
Layout file/res/layout/activity_select_photo.xml:
Next we get the code SelectPhotoActivity in the image Activity:
Public class SelectPhotoActivity extends Activity implements OnClickListener {/** use a camera to take a picture */public static final int SELECT_PIC_BY_TACK_PHOTO = 1; /** use the image in the album */public static final int SELECT_PIC_BY_PICK_PHOTO = 2;/** enable the camera */private Button btn_take_photo;/** enable the album */private Button btn_pick_photo; /** cancel */private Button btn_cancel;/** the obtained image path */private String picPath; private Intent lastIntent; pri Vate Uri photoUri;/** get the KEY of the image path from Intent */public static final String KEY_PHOTO_PATH = photo_path; @ Overrideprotected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_select_photo); btn_take_photo = (Button) findViewById (R. id. btn_take_photo); btn_pick_photo = (Button) findViewById (R. id. btn_pick_photo); btn_cancel = (Button) findViewById (R. id. Btn_cancel); lastIntent = getIntent (); terminate (this); btn_cancel.setOnClickListener (this);} @ Overridepublic void onClick (View v) {switch (v. getId () {case R. id. btn_take_photo: // enable camera takePhoto (); break; case R. id. btn_pick_photo: // enable the album pickPhoto (); break; case R. id. btn_cancel: // cancel this operation. finish (); break; default: break;}/*** image acquisition */pr Ivate void takePhoto () {// before taking the photo, you should first determine whether the SD card contains String SDState = Environment. getExternalStorageState (); if (SDState. equals (Environment. MEDIA_MOUNTED) {Intent intent = new Intent (MediaStore. ACTION_IMAGE_CAPTURE); // android. media. action. IMAGE_CAPTURE/***** note that the following operations use a camera to take a photo, the image after being taken is stored in the album. This method has the advantage of obtaining the original image after being taken. * If ContentValues is not used to store the photo path, the image obtained after the photo is thumbnail unclear */ContentValues values = new ContentValu Es (); photoUri = this. getContentResolver (). insert (MediaStore. images. media. EXTERNAL_CONTENT_URI, values); intent. putExtra (android. provider. mediaStore. EXTRA_OUTPUT, photoUri); startActivityForResult (intent, SELECT_PIC_BY_TACK_PHOTO);} else {Toast. makeText (getApplicationContext (), memory card does not exist, Toast. LENGTH_SHORT ). show () ;}/ ***** retrieve image from album */private void pickPhoto () {Intent intent = new Intent (); intent. setType (I Mage/*); intent. setAction (Intent. ACTION_GET_CONTENT); startActivityForResult (intent, SELECT_PIC_BY_PICK_PHOTO);} @ Overridepublic boolean onTouchEvent (MotionEvent event) {finish (); return super. onTouchEvent (event) ;}@ Overrideprotected void onActivityResult (int requestCode, int resultCode, Intent data) {if (resultCode = Activity. RESULT_ OK) {doPhoto (requestCode, data);} super. onActivityResult (requestCode, ResultCode, data);}/*** after selecting an image, obtain the image path ** @ param requestCode * @ param data */private void doPhoto (int requestCode, Intent data) {if (requestCode = SELECT_PIC_BY_PICK_PHOTO) {// retrieve an image from the album. if (data = null) {Toast. makeText (getApplicationContext (), select image file error, Toast. LENGTH_SHORT ). show (); return;} photoUri = data. getData (); if (photoUri = null) {Toast. makeText (getApplicationContext (), an error occurred while selecting the image file, Toast. LENGTH_SHORT ). show (); return ;}string [] pojo = {MediaStore. images. media. DATA}; Cursor cursor = managedQuery (photoUri, pojo, null); if (cursor! = Null) {int columnIndex = cursor. getColumnIndexOrThrow (pojo [0]); cursor. moveToFirst (); picPath = cursor. getString (columnIndex); cursor. close ();} if (picPath! = Null & (picPath.endsWith(.png) | picPath. endsWith (. PNG) | picPath.endsWith(.jpg) | picPath. endsWith (. JPG) {lastIntent. putExtra (KEY_PHOTO_PATH, picPath); setResult (Activity. RESULT_ OK, lastIntent); finish ();} else {Toast. makeText (getApplicationContext (), incorrect image file selection, Toast. LENGTH_SHORT ). show ();}}}
Because this Activity is set to the Dialog mode, you need to set the style,/res/values/styles. xml in the configuration file to add the following:
Set the style under the Activity node:
Add permission:
The running effect is as follows:
2. Get an image by taking a photo or gallery (cropping required)
The first method to obtain images is not cropped, but most projects require cropping images before use, such as modifying user portraits. Next, we will provide the image cropping code:
Public class CropPictureActivity extends Activity {/** ImageView object */private ImageView iv_photo; private String [] items = new String [] {select a local image and take a photo }; /** avatar name */private static final String IMAGE_FILE_NAME = image.jpg;/** Request Code */private static final int IMAGE_REQUEST_CODE = 0; private static final int CAMERA_REQUEST_CODE = 1; private static final int RESULT_REQUEST_CODE = 2; @ Overrideprotected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_crop); iv_photo = (ImageView) findViewById (R. id. iv_photo); iv_photo.setOnClickListener (new OnClickListener () {@ Overridepublic void onClick (View v) {showDialog ();}});} /*** display selection dialog box */private void showDialog () {new AlertDialog. builder (this ). setTitle (set Avatar ). setItems (items, new DialogInterface. onClickListener () {@ Overridepublic void onClick (DialogInterface diich, int which) {switch (which) {case 0: Intent intentFromGallery = new Intent (); intentFromGallery. setType (image/*); // sets the file type intentFromGallery. setAction (Intent. ACTION_GET_CONTENT); startActivityForResult (intentFromGallery, IMAGE_REQUEST_CODE); break; case 1: intentFromCapture = new Intent (MediaStore. ACTION_IMAGE_CAPTURE); // determines whether the memory card can be used for storage. Tring state = Environment. getExternalStorageState (); if (state. equals (Environment. MEDIA_MOUNTED) {File path = Environment. getExternalStoragePublicDirectory (Environment. DIRECTORY_DCIM); File file = new File (path, IMAGE_FILE_NAME); intentFromCapture. putExtra (MediaStore. EXTRA_OUTPUT, Uri. fromFile (file);} startActivityForResult (intentFromCapture, CAMERA_REQUEST_CODE); break ;}}}). setNegativeButton (cancel, new D IalogInterface. onClickListener () {@ Overridepublic void onClick (DialogInterface dialog, int which) {dialog. dismiss ();}}). show () ;}@ Overrideprotected void onActivityResult (int requestCode, int resultCode, Intent data) {// The result code is not equal to if (resultCode! = RESULT_CANCELED) {switch (requestCode) {case IMAGE_REQUEST_CODE: startPhotoZoom (data. getData (); break; case CAMERA_REQUEST_CODE: // determines whether the memory card can be used. String state = Environment can be stored. getExternalStorageState (); if (state. equals (Environment. MEDIA_MOUNTED) {File path = Environment. getExternalStoragePublicDirectory (Environment. DIRECTORY_DCIM); File tempFile = new File (path, IMAGE_FILE_NAME); startPhotoZoom (Uri. FromFile (tempFile);} else {Toast. makeText (getApplicationContext (), no memory card found, unable to store photos !, Toast. LENGTH_SHORT). show ();} break; case RESULT_REQUEST_CODE: // if (data! = Null) {getImageToView (data) ;}break ;}} super. onActivityResult (requestCode, resultCode, data);}/*** image cropping method implementation ** @ param uri */public void startPhotoZoom (Uri uri) {Intent intent = new Intent (com. android. camera. action. CROP); intent. setDataAndType (uri, image/*); // you can specify the intent for cropping. putExtra (crop, true); // aspectX aspectY is a width-to-height ratio intent. putExtra (aspectX, 1); intent. putExtra (aspectY, 1); // outputX outputY is the width and height of the cropped image. Ntent. putExtra (outputx, 340); intent. putExtra (outputY, 340); intent. putExtra (return-data, true); startActivityForResult (intent, RESULT_REQUEST_CODE );} /*** Save the cropped image data ** @ param picdata */private void getImageToView (Intent data) {Bundle extras = data. getExtras (); if (extras! = Null) {Bitmap photo = extras. getParcelable (data); Drawable drawable = new BitmapDrawable (this. getResources (), photo); iv_photo.setImageDrawable (drawable );}}}
:
In this Activity for ease of processing, I didn't start a Dialog style Activity when selecting an image, so I directly prompted the user to select a normal Dialog box. The effect may be better. In fact, the implementation principle is relatively simple. to crop an image, send an Intent request and call all apps on the device that have the image clipping function to crop the image, in addition to the image library that comes with the android system, my device also has the "quick Image Browsing" app, which also comes with an image cropping function. After all the images are selected, A selection prompt is displayed. You can select which app to use to crop the image in the functional area.
The above code has been tested on the simulator. Because the simulator does not support the camera well, there is no demonstration to enable the camera to take pictures. If you are interested, please download the source code of this Demo first, run it on your phone and try it out. If you miss it, you are welcome to criticize and correct it!
Download the source code here