Android · 2015年4月27日 0

Android 4.4从图库选择图片,获取图片路径并裁剪

     最近在做一个从图库选择图片或拍照,然后裁剪的功能.本来是没问题的,一直在用

  1. Intent intent=new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

的方式来做,是调用系统图库来做,但是发现如果有图片是同步到google相册的话,图库里面能看到一个auto backup的目录,点进去选图片的话是无法获取到图片的路径的.因为那些图片根本就不存在于手机上.然后看到无论是百度贴吧,Instagram,或者还有些会选取图片做修改的app,都是用一个很漂亮的图片选择器(4.4以上,4.3的还是用系统旧的图库).

而这个图片选择器可以屏蔽掉那个auto backup的目录.所以就开始打算用这个图片选择器来选图片了.
这个方法就是

  1. Intent intent=new Intent(Intent.ACTION_GET_CONTENT);//ACTION_OPEN_DOCUMENT
  2. intent.addCategory(Intent.CATEGORY_OPENABLE);
  3. intent.setType(“image/jpeg”);
  4. if(android.os.Build.VERSION.SDK_INT>=android.os.Build.VERSION_CODES.KITKAT){
  5.         startActivityForResult(intent, SELECT_PIC_KITKAT);
  6. }else{
  7.         startActivityForResult(intent, SELECT_PIC);
  8. }

 

为什么要分开不同版本呢?其实在4.3或以下可以直接用ACTION_GET_CONTENT的,在4.4或以上,官方建议用ACTION_OPEN_DOCUMENT,但其实都不算太大区别,区别是他们返回的Uri,那个才叫大区别.这就是困扰了我一整天的问题所在了.

4.3或以下,选了图片之后,根据Uri来做处理,很多帖子都有了,我就不详细说了.主要是4.4,如果使用上面pick的原生方法来选图,返回的uri还是正常的,但如果用ACTION_GET_CONTENT的方法,返回的uri跟4.3是完全不一样的,4.3返回的是带文件路径的,而4.4返回的却是content://com.android.providers.media.documents/document/image:3951这样的,没有路径,只有图片编号的uri.这就导致接下来无法根据图片路径来裁剪的步骤了.

还好找了很多方法,包括加权限啊什么的,中间还试过用一些方法,自己的app没崩溃,倒是让系统图库崩溃了,引发了java.lang.SecurityException.

  1. Caused by: java.lang.SecurityException: Permission Denial: opening provider com.android.providers.media.MediaDocumentsProvider from ProcessRecord{437b5d88 9494:com.google.android.gallery3d/u0a20} (pid=9494, uid=10020) requires android.permission.MANAGE_DOCUMENTS or android.permission.MANAGE_DOCUMENTS

看来4.4的系统还是有些bug.重点来了,4.4得到的uri,需要以下方法来获取文件的路径

  1. public static String getPath(final Context context, final Uri uri) {
  2.     final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
  3.     // DocumentProvider
  4.     if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
  5.         // ExternalStorageProvider
  6.         if (isExternalStorageDocument(uri)) {
  7.             final String docId = DocumentsContract.getDocumentId(uri);
  8.             final String[] split = docId.split(“:”);
  9.             final String type = split[0];
  10.             if (“primary”.equalsIgnoreCase(type)) {
  11.                 return Environment.getExternalStorageDirectory() + “/” + split[1];
  12.             }
  13.             // TODO handle non-primary volumes
  14.         }
  15.         // DownloadsProvider
  16.         else if (isDownloadsDocument(uri)) {
  17.             final String id = DocumentsContract.getDocumentId(uri);
  18.             final Uri contentUri = ContentUris.withAppendedId(
  19.                     Uri.parse(“content://downloads/public_downloads”), Long.valueOf(id));
  20.             return getDataColumn(context, contentUri, nullnull);
  21.         }
  22.         // MediaProvider
  23.         else if (isMediaDocument(uri)) {
  24.             final String docId = DocumentsContract.getDocumentId(uri);
  25.             final String[] split = docId.split(“:”);
  26.             final String type = split[0];
  27.             Uri contentUri = null;
  28.             if (“image”.equals(type)) {
  29.                 contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
  30.             } else if (“video”.equals(type)) {
  31.                 contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
  32.             } else if (“audio”.equals(type)) {
  33.                 contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
  34.             }
  35.             final String selection = “_id=?”;
  36.             final String[] selectionArgs = new String[] {
  37.                     split[1]
  38.             };
  39.             return getDataColumn(context, contentUri, selection, selectionArgs);
  40.         }
  41.     }
  42.     // MediaStore (and general)
  43.     else if (“content”.equalsIgnoreCase(uri.getScheme())) {
  44.         // Return the remote address
  45.         if (isGooglePhotosUri(uri))
  46.             return uri.getLastPathSegment();
  47.         return getDataColumn(context, uri, nullnull);
  48.     }
  49.     // File
  50.     else if (“file”.equalsIgnoreCase(uri.getScheme())) {
  51.         return uri.getPath();
  52.     }
  53.     return null;
  54. }
  55. /**
  56.  * Get the value of the data column for this Uri. This is useful for
  57.  * MediaStore Uris, and other file-based ContentProviders.
  58.  *
  59.  * @param context The context.
  60.  * @param uri The Uri to query.
  61.  * @param selection (Optional) Filter used in the query.
  62.  * @param selectionArgs (Optional) Selection arguments used in the query.
  63.  * @return The value of the _data column, which is typically a file path.
  64.  */
  65. public static String getDataColumn(Context context, Uri uri, String selection,
  66.         String[] selectionArgs) {
  67.     Cursor cursor = null;
  68.     final String column = “_data”;
  69.     final String[] projection = {
  70.             column
  71.     };
  72.     try {
  73.         cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
  74.                 null);
  75.         if (cursor != null && cursor.moveToFirst()) {
  76.             final int index = cursor.getColumnIndexOrThrow(column);
  77.             return cursor.getString(index);
  78.         }
  79.     } finally {
  80.         if (cursor != null)
  81.             cursor.close();
  82.     }
  83.     return null;
  84. }
  85. /**
  86.  * @param uri The Uri to check.
  87.  * @return Whether the Uri authority is ExternalStorageProvider.
  88.  */
  89. public static boolean isExternalStorageDocument(Uri uri) {
  90.     return “com.android.externalstorage.documents”.equals(uri.getAuthority());
  91. }
  92. /**
  93.  * @param uri The Uri to check.
  94.  * @return Whether the Uri authority is DownloadsProvider.
  95.  */
  96. public static boolean isDownloadsDocument(Uri uri) {
  97.     return “com.android.providers.downloads.documents”.equals(uri.getAuthority());
  98. }
  99. /**
  100.  * @param uri The Uri to check.
  101.  * @return Whether the Uri authority is MediaProvider.
  102.  */
  103. public static boolean isMediaDocument(Uri uri) {
  104.     return “com.android.providers.media.documents”.equals(uri.getAuthority());
  105. }
  106. /**
  107.  * @param uri The Uri to check.
  108.  * @return Whether the Uri authority is Google Photos.
  109.  */
  110. public static boolean isGooglePhotosUri(Uri uri) {
  111.     return “com.google.android.apps.photos.content”.equals(uri.getAuthority());
  112. }

 

这样,就可以在4.4上用漂亮的图片选择器,选到我们想要的文件,又不会出问题了.

昨天发现了个bug,如果在4.4上面不用”图片”来选,用”图库”来选,就会无法读取到图片路径,所以只需要加个判断,如果是用旧方式来选,就用旧方式来读,就是如果
DocumentsContract.isDocumentUri(context, uri) 返回false的话,就用旧的方式

  1. public static String selectImage(Context context,Intent data){
  2.         Uri selectedImage = data.getData();
  3. //      Log.e(TAG, selectedImage.toString());
  4.         if(selectedImage!=null){
  5.             String uriStr=selectedImage.toString();
  6.             String path=uriStr.substring(10,uriStr.length());
  7.             if(path.startsWith(“com.sec.android.gallery3d”)){
  8.                 Log.e(TAG, “It’s auto backup pic path:”+selectedImage.toString());
  9.                 return null;
  10.             }
  11.         }
  12.         String[] filePathColumn = { MediaStore.Images.Media.DATA };
  13.         Cursor cursor = context.getContentResolver().query(selectedImage,filePathColumn, nullnullnull);
  14.         cursor.moveToFirst();
  15.         int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
  16.         String picturePath = cursor.getString(columnIndex);
  17.         cursor.close();
  18.         return picturePath;
  19.     }

这样就OK的了
转自:http://blog.csdn.net/tempersitu/article/details/20557383

 

android拍照图片选取与图片剪裁

   转载:http://blog.csdn.net/allen315410/article/details/39994913

最近从以前的项目中扒下来一个常用的模块,在这里有必要记录一下的,就是android上获取图片以及裁剪图片,怎么样?这个功能是不是很常用啊,你随便打开一个App,只要它有注册功能都会有设置人物头像的功能,尤其在内容型的app中更为常见,那么这些功能是怎么实现的呢?今天,在这里就记录一下好了,防止以后的项目中也会用到,就直接拿来用好了。

1.通过拍照或者图册获取图片(不需要剪裁)

这种获取图片的方式就比较次了,因为不设置图片的剪裁功能,有可能因为图片过大,导致OOM,但是这种方式也是有必要讲一下的,其获取图片的方式有两种,一是调用系统相机实时拍摄一张图片,二十打开设备上已有的图库,在图库中选择一张照片。这两种方式实现方法都是一个道理,无非就是通过Intent调用系统的东西。下面是源码,首先是图片选择方式的Activity,这个Activity被设置成了Dialog模式,需要进行设置一下。

布局文件/res/layout/activity_select_photo.xml:

  1. <?xml version=“1.0” encoding=“utf-8”?>
  2. <RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”
  3.     android:layout_width=“fill_parent”
  4.     android:layout_height=“wrap_content”
  5.     android:gravity=“center_horizontal” >
  6.     <LinearLayout
  7.         android:id=“@+id/dialog_layout”
  8.         android:layout_width=“fill_parent”
  9.         android:layout_height=“wrap_content”
  10.         android:layout_alignParentBottom=“true”
  11.         android:layout_marginLeft=“10dip”
  12.         android:layout_marginRight=“10dip”
  13.         android:gravity=“center_horizontal”
  14.         android:orientation=“vertical” >
  15.         <LinearLayout
  16.             android:layout_width=“fill_parent”
  17.             android:layout_height=“wrap_content”
  18.             android:background=“@drawable/select_photo_up_bg”
  19.             android:orientation=“vertical”
  20.             android:paddingBottom=“5dp”
  21.             android:paddingTop=“5dp” >
  22.             <Button
  23.                 android:id=“@+id/btn_take_photo”
  24.                 android:layout_width=“fill_parent”
  25.                 android:layout_height=“35dp”
  26.                 android:background=“@drawable/select_photo_bg”
  27.                 android:text=“拍照选取”
  28.                 android:textStyle=“bold” />
  29.             <View
  30.                 android:layout_width=“fill_parent”
  31.                 android:layout_height=“0.5px”
  32.                 android:background=“#828282” />
  33.             <Button
  34.                 android:id=“@+id/btn_pick_photo”
  35.                 android:layout_width=“fill_parent”
  36.                 android:layout_height=“35dp”
  37.                 android:layout_marginTop=“0dip”
  38.                 android:background=“@drawable/select_photo_bg”
  39.                 android:text=“相册选取”
  40.                 android:textStyle=“bold” />
  41.         </LinearLayout>
  42.         <Button
  43.             android:id=“@+id/btn_cancel”
  44.             android:layout_width=“fill_parent”
  45.             android:layout_height=“35dp”
  46.             android:layout_marginTop=“20dip”
  47.             android:background=“@drawable/select_photo_bg”
  48.             android:paddingBottom=“5dp”
  49.             android:paddingTop=“5dp”
  50.             android:text=“取消”
  51.             android:textColor=“#ffff0000”
  52.             android:textStyle=“bold” />
  53.     </LinearLayout>
  54. </RelativeLayout>

接着是获取图片Activity里的代码SelectPhotoActivity:

  1. public class SelectPhotoActivity extends Activity implements OnClickListener {
  2.     /** 使用照相机拍照获取图片 */
  3.     public static final int SELECT_PIC_BY_TACK_PHOTO = 1;
  4.     /** 使用相册中的图片 */
  5.     public static final int SELECT_PIC_BY_PICK_PHOTO = 2;
  6.     /** 开启相机 */
  7.     private Button btn_take_photo;
  8.     /** 开启图册 */
  9.     private Button btn_pick_photo;
  10.     /** 取消 */
  11.     private Button btn_cancel;
  12.     /** 获取到的图片路径 */
  13.     private String picPath;
  14.     private Intent lastIntent;
  15.     private Uri photoUri;
  16.     /** 从Intent获取图片路径的KEY */
  17.     public static final String KEY_PHOTO_PATH = “photo_path”;
  18.     @Override
  19.     protected void onCreate(Bundle savedInstanceState) {
  20.         super.onCreate(savedInstanceState);
  21.         setContentView(R.layout.activity_select_photo);
  22.         btn_take_photo = (Button) findViewById(R.id.btn_take_photo);
  23.         btn_pick_photo = (Button) findViewById(R.id.btn_pick_photo);
  24.         btn_cancel = (Button) findViewById(R.id.btn_cancel);
  25.         lastIntent = getIntent();
  26.         btn_take_photo.setOnClickListener(this);
  27.         btn_pick_photo.setOnClickListener(this);
  28.         btn_cancel.setOnClickListener(this);
  29.     }
  30.     @Override
  31.     public void onClick(View v) {
  32.         switch (v.getId()) {
  33.             case R.id.btn_take_photo : // 开启相机
  34.                 takePhoto();
  35.                 break;
  36.             case R.id.btn_pick_photo : // 开启图册
  37.                 pickPhoto();
  38.                 break;
  39.             case R.id.btn_cancel : // 取消操作
  40.                 this.finish();
  41.                 break;
  42.             default :
  43.                 break;
  44.         }
  45.     }
  46.     /**
  47.      * 拍照获取图片
  48.      */
  49.     private void takePhoto() {
  50.         // 执行拍照前,应该先判断SD卡是否存在
  51.         String SDState = Environment.getExternalStorageState();
  52.         if (SDState.equals(Environment.MEDIA_MOUNTED)) {
  53.             Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);// “android.media.action.IMAGE_CAPTURE”
  54.             /***
  55.              * 需要说明一下,以下操作使用照相机拍照,拍照后的图片会存放在相册中的 这里使用的这种方式有一个好处就是获取的图片是拍照后的原图
  56.              * 如果不实用ContentValues存放照片路径的话,拍照后获取的图片为缩略图不清晰
  57.              */
  58.             ContentValues values = new ContentValues();
  59.             photoUri = this.getContentResolver().insert(
  60.                     MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
  61.             intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, photoUri);
  62.             startActivityForResult(intent, SELECT_PIC_BY_TACK_PHOTO);
  63.         } else {
  64.             Toast.makeText(getApplicationContext(), “内存卡不存在”,
  65.                     Toast.LENGTH_SHORT).show();
  66.         }
  67.     }
  68.     /***
  69.      * 从相册中取图片
  70.      */
  71.     private void pickPhoto() {
  72.         Intent intent = new Intent();
  73.         intent.setType(“image/*”);
  74.         intent.setAction(Intent.ACTION_GET_CONTENT);
  75.         startActivityForResult(intent, SELECT_PIC_BY_PICK_PHOTO);
  76.     }
  77.     @Override
  78.     public boolean onTouchEvent(MotionEvent event) {
  79.         finish();
  80.         return super.onTouchEvent(event);
  81.     }
  82.     @Override
  83.     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  84.         if (resultCode == Activity.RESULT_OK) {
  85.             doPhoto(requestCode, data);
  86.         }
  87.         super.onActivityResult(requestCode, resultCode, data);
  88.     }
  89.     /**
  90.      * 选择图片后,获取图片的路径
  91.      *
  92.      * @param requestCode
  93.      * @param data
  94.      */
  95.     private void doPhoto(int requestCode, Intent data) {
  96.         if (requestCode == SELECT_PIC_BY_PICK_PHOTO) {// 从相册取图片,有些手机有异常情况,请注意
  97.             if (data == null) {
  98.                 Toast.makeText(getApplicationContext(), “选择图片文件出错”,
  99.                         Toast.LENGTH_SHORT).show();
  100.                 return;
  101.             }
  102.             photoUri = data.getData();
  103.             if (photoUri == null) {
  104.                 Toast.makeText(getApplicationContext(), “选择图片文件出错”,
  105.                         Toast.LENGTH_SHORT).show();
  106.                 return;
  107.             }
  108.         }
  109.         String[] pojo = {MediaStore.Images.Media.DATA};
  110.         Cursor cursor = managedQuery(photoUri, pojo, nullnullnull);
  111.         if (cursor != null) {
  112.             int columnIndex = cursor.getColumnIndexOrThrow(pojo[0]);
  113.             cursor.moveToFirst();
  114.             picPath = cursor.getString(columnIndex);
  115.             cursor.close();
  116.         }
  117.         if (picPath != null
  118.                 && (picPath.endsWith(“.png”) || picPath.endsWith(“.PNG”)
  119.                         || picPath.endsWith(“.jpg”) || picPath.endsWith(“.JPG”))) {
  120.             lastIntent.putExtra(KEY_PHOTO_PATH, picPath);
  121.             setResult(Activity.RESULT_OK, lastIntent);
  122.             finish();
  123.         } else {
  124.             Toast.makeText(getApplicationContext(), “选择图片文件不正确”,
  125.                     Toast.LENGTH_SHORT).show();
  126.         }
  127.     }
  128. }

因为这Activity是要设置成Dialog模式的,所以需要在清单文件中设置一下style,/res/values/styles.xml里添加如下:

  1. <!– 选取照片的Activity的样式风格,采取对话框的风格 –>
  2.     <style name=“AnimBottom” parent=“@android:style/Animation”>
  3.         <item name=“android:windowEnterAnimation”>@anim/push_bottom_in</item>
  4.         <item name=“android:windowExitAnimation”>@anim/push_bottom_out</item>
  5.     </style>
  6.     <style name=“DialogStyleBottom” parent=“android:Theme.Dialog”>
  7.         <item name=“android:windowAnimationStyle”>@style/AnimBottom</item>
  8.         <item name=“android:windowFrame”>@null</item>
  9.         <!– 边框 –>
  10.         <item name=“android:windowIsFloating”>false</item>
  11.         <!– 是否浮现在activity之上 –>
  12.         <item name=“android:windowIsTranslucent”>true</item>
  13.         <!– 半透明 –>
  14.         <item name=“android:windowNoTitle”>true</item>
  15.         <!– 无标题 –>
  16.         <item name=“android:windowBackground”>@android:color/transparent</item>
  17.         <!– 背景透明 –>
  18.         <item name=“android:backgroundDimEnabled”>true</item>
  19.         <!– 模糊 –>
  20.     </style>

在Activity的节点下,设置这个style:

  1. <activity
  2.             android:name=“com.example.croppictrue.SelectPhotoActivity”
  3.             android:screenOrientation=“portrait”
  4.             android:theme=“@style/DialogStyleBottom” >
  5.         </activity>

添加权限:

  1. <uses-permission android:name=“android.permission.WRITE_EXTERNAL_STORAGE” />

运行效果如下:

   

2.通过拍照或者图册获取图片(需要剪裁)

上面第一种方式获取图片是没有经过剪裁的,但是大多项目需求是需要剪裁图片后再使用,例如修改用户头像等等功能。那么,下面,就奉上剪裁图片的代码吧:

  1. public class CropPictureActivity extends Activity {
  2.     /** ImageView对象 */
  3.     private ImageView iv_photo;
  4.     private String[] items = new String[]{“选择本地图片”“拍照”};
  5.     /** 头像名称 */
  6.     private static final String IMAGE_FILE_NAME = “image.jpg”;
  7.     /** 请求码 */
  8.     private static final int IMAGE_REQUEST_CODE = 0;
  9.     private static final int CAMERA_REQUEST_CODE = 1;
  10.     private static final int RESULT_REQUEST_CODE = 2;
  11.     @Override
  12.     protected void onCreate(Bundle savedInstanceState) {
  13.         super.onCreate(savedInstanceState);
  14.         setContentView(R.layout.activity_crop);
  15.         iv_photo = (ImageView) findViewById(R.id.iv_photo);
  16.         iv_photo.setOnClickListener(new OnClickListener() {
  17.             @Override
  18.             public void onClick(View v) {
  19.                 showDialog();
  20.             }
  21.         });
  22.     }
  23.     /**
  24.      * 显示选择对话框
  25.      */
  26.     private void showDialog() {
  27.         new AlertDialog.Builder(this)
  28.                 .setTitle(“设置头像”)
  29.                 .setItems(items, new DialogInterface.OnClickListener() {
  30.                     @Override
  31.                     public void onClick(DialogInterface dialog, int which) {
  32.                         switch (which) {
  33.                             case 0 :
  34.                                 Intent intentFromGallery = new Intent();
  35.                                 intentFromGallery.setType(“image/*”); // 设置文件类型
  36.                                 intentFromGallery
  37.                                         .setAction(Intent.ACTION_GET_CONTENT);
  38.                                 startActivityForResult(intentFromGallery,
  39.                                         IMAGE_REQUEST_CODE);
  40.                                 break;
  41.                             case 1 :
  42.                                 Intent intentFromCapture = new Intent(
  43.                                         MediaStore.ACTION_IMAGE_CAPTURE);
  44.                                 // 判断存储卡是否可以用,可用进行存储
  45.                                 String state = Environment
  46.                                         .getExternalStorageState();
  47.                                 if (state.equals(Environment.MEDIA_MOUNTED)) {
  48.                                     File path = Environment
  49.                                             .getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
  50.                                     File file = new File(path, IMAGE_FILE_NAME);
  51.                                     intentFromCapture.putExtra(
  52.                                             MediaStore.EXTRA_OUTPUT,
  53.                                             Uri.fromFile(file));
  54.                                 }
  55.                                 startActivityForResult(intentFromCapture,
  56.                                         CAMERA_REQUEST_CODE);
  57.                                 break;
  58.                         }
  59.                     }
  60.                 })
  61.                 .setNegativeButton(“取消”new DialogInterface.OnClickListener() {
  62.                     @Override
  63.                     public void onClick(DialogInterface dialog, int which) {
  64.                         dialog.dismiss();
  65.                     }
  66.                 }).show();
  67.     }
  68.     @Override
  69.     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  70.         // 结果码不等于取消时候
  71.         if (resultCode != RESULT_CANCELED) {
  72.             switch (requestCode) {
  73.                 case IMAGE_REQUEST_CODE :
  74.                     startPhotoZoom(data.getData());
  75.                     break;
  76.                 case CAMERA_REQUEST_CODE :
  77.                     // 判断存储卡是否可以用,可用进行存储
  78.                     String state = Environment.getExternalStorageState();
  79.                     if (state.equals(Environment.MEDIA_MOUNTED)) {
  80.                         File path = Environment
  81.                                 .getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
  82.                         File tempFile = new File(path, IMAGE_FILE_NAME);
  83.                         startPhotoZoom(Uri.fromFile(tempFile));
  84.                     } else {
  85.                         Toast.makeText(getApplicationContext(),
  86.                                 “未找到存储卡,无法存储照片!”, Toast.LENGTH_SHORT).show();
  87.                     }
  88.                     break;
  89.                 case RESULT_REQUEST_CODE : // 图片缩放完成后
  90.                     if (data != null) {
  91.                         getImageToView(data);
  92.                     }
  93.                     break;
  94.             }
  95.         }
  96.         super.onActivityResult(requestCode, resultCode, data);
  97.     }
  98.     /**
  99.      * 裁剪图片方法实现
  100.      *
  101.      * @param uri
  102.      */
  103.     public void startPhotoZoom(Uri uri) {
  104.         Intent intent = new Intent(“com.android.camera.action.CROP”);
  105.         intent.setDataAndType(uri, “image/*”);
  106.         // 设置裁剪
  107.         intent.putExtra(“crop”“true”);
  108.         // aspectX aspectY 是宽高的比例
  109.         intent.putExtra(“aspectX”1);
  110.         intent.putExtra(“aspectY”1);
  111.         // outputX outputY 是裁剪图片宽高
  112.         intent.putExtra(“outputX”340);
  113.         intent.putExtra(“outputY”340);
  114.         intent.putExtra(“return-data”true);
  115.         startActivityForResult(intent, RESULT_REQUEST_CODE);
  116.     }
  117.     /**
  118.      * 保存裁剪之后的图片数据
  119.      *
  120.      * @param picdata
  121.      */
  122.     private void getImageToView(Intent data) {
  123.         Bundle extras = data.getExtras();
  124.         if (extras != null) {
  125.             Bitmap photo = extras.getParcelable(“data”);
  126.             Drawable drawable = new BitmapDrawable(this.getResources(), photo);
  127.             iv_photo.setImageDrawable(drawable);
  128.         }
  129.     }
  130. }

效果图:

     

在这个Activity里为了简便处理,我没有在选择图片时候start一个Dialog风格的Activity了,就直接一个普通的对话框提示用户选择,效果也许。其实实现的原理都比较简单,实现图片的剪裁就是发一个Intent请求,调用设备上所有具有剪裁图片功能的app去剪裁图片,我的设备上除了android系统自带的图库以外,还装有“快图浏览”这个app,这个app也自带一个图片剪裁的功能,所有当选择好图片后,会出现一个选择提示,用户可以根据提示选择到底使用哪个app提供的剪裁功能区剪裁图片。
以上代码均在模拟器上测试过,由于模拟器对相机支持的不好,所以就没有演示打开相机拍摄图片了,有兴趣的朋友可以先请下载这个Demo的源码,运行在手机上试试看效果如何,如若疏漏之后,欢迎大家批评指正!

源码请在这里下载

 

Share this: