图片拍照或相册选择的实现以及裁剪功能

/**
*   开发android项目时使用到的一个图片功能,觉得还可以,所以分享一下
 * 带有选择图片的Activity,子类只要对应的控件监听事件实现setImageToView就可以对图片进行相应的处理了
 * @author lt
 */
public abstract class BaseGetImageActivity extends BaseActivity {

   protected static final int CHOOSE_PICTURE = 0;
   protected static final int TAKE_PICTURE = 1;
   protected static final int CHOOSE_PICTURE_SDK_INT = 2;
   protected static final int CROP_SMALL_PICTURE = 10;
   protected static Uri  tempUri;
   protected static Uri uri;

   /**
    * 显示修改头像的对话框
    */
   protected void showChooseIcon() {
      AlertDialog.Builder builder = new AlertDialog.Builder(this);
      builder.setTitle("设置头像");
      String[] items = { "选择本地照片", "拍照" };
      builder.setNegativeButton("取消", null);
      builder.setItems(items, new OnClickListener() {

         @Override
         public void onClick(DialogInterface dialog, int which) {
            switch (which) {
               case CHOOSE_PICTURE:
               
  /*附录引用:http://blog.csdn.net/tempersitu/article/details/20557383
 最近在做一个从图库选择图片或拍照,然后裁剪的功能.本来是没问题的,一直在用 
 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的目录.所以就开始打算用这个图片选择器来选图片了.这个方法就是
Intent intent=new Intent(Intent.ACTION_GET_CONTENT);//ACTION_OPEN_DOCUMENT  
intent.addCategory(Intent.CATEGORY_OPENABLE);  
intent.setType("image/jpeg");  
if(android.os.Build.VERSION.SDK_INT>=android.os.Build.VERSION_CODES.KITKAT){                  
        startActivityForResult(intent, SELECT_PIC_KITKAT);    
}else{                
        startActivityForResult(intent, SELECT_PIC);   
}   
为什么要分开不同版本呢?其实在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.这就导致接下来无法根据图片路径来裁剪的步骤了.
 所以进行下面操作:
  
   */              
                  if (Build.VERSION.SDK_INT < 19){
                     Intent openAlbumIntent = new Intent();
                     openAlbumIntent.setType("image/*");
                     openAlbumIntent.setAction(Intent.ACTION_GET_CONTENT);
                     startActivityForResult(openAlbumIntent, CHOOSE_PICTURE_SDK_INT);
                  }else {
                     Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
                     intent.addCategory(Intent.CATEGORY_OPENABLE);
                     intent.setType("image/*");
                     startActivityForResult(intent, CHOOSE_PICTURE);
                  }
                  break;
               case TAKE_PICTURE:
                  Intent openCameraIntent = new Intent(
                        MediaStore.ACTION_IMAGE_CAPTURE);
                  tempUri = Uri.fromFile(new File(Environment
                        .getExternalStorageDirectory(), "image.jpg"));
                  // 指定照片保存路径(SD卡),image.jpg为一个临时文件,每次拍照后这个图片都会被替换
                  openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempUri);
                  startActivityForResult(openCameraIntent, TAKE_PICTURE);
                  break;
            }
         }
      });
      builder.create().show();
   }

   @TargetApi(Build.VERSION_CODES.KITKAT)
   @Override
   protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      super.onActivityResult(requestCode, resultCode, data);
      if (resultCode == RESULT_OK) {
         switch (requestCode) {
            case TAKE_PICTURE:
               startPhotoZoom(tempUri);
               break;
            case CHOOSE_PICTURE:
               if (DocumentsContract.isDocumentUri(this, data.getData())){
                  try {
                     uri = Uri.fromFile(new File(getPath(this,data.getData())));
                  } catch (Exception e) {
                     e.printStackTrace();
                  }
               }else{
                  uri = Uri.fromFile(new File(selectImage(this,data)));
               }
               startPhotoZoom(uri);
               break;
            case CHOOSE_PICTURE_SDK_INT:
               startPhotoZoom(data.getData());
               break;
            case CROP_SMALL_PICTURE:
               if (data != null) {
                  data.putExtra("picUri",tempUri);
                  setImageToView(data);
               }
               break;
         }
      }
   }

   /**
    * 裁剪图片方法实现
    *
    * @param uri
    */
 protected void startPhotoZoom(Uri uri) {
   if (uri == null) {
      Log.i("tag", "The uri is not exist.");
   }
   tempUri = uri;
   Intent intent = new Intent("com.android.camera.action.CROP");
   intent.setDataAndType(uri, "image/*");
   // 设置裁剪
   intent.putExtra("crop", "true");
   // aspectX aspectY 是宽高的比例
   intent.putExtra("aspectX", 1);
   intent.putExtra("aspectY", 1);
   // outputX outputY 是裁剪图片宽高
   intent.putExtra("outputX", 300);
   intent.putExtra("outputY", 300);
   intent.putExtra("return-data", true);
   startActivityForResult(intent, CROP_SMALL_PICTURE);
}
   /**
    * 保存裁剪之后的图片数据,由子类实现
    *
    * @param
    *
    * @param picdata
    */
   protected void setImageToView(Intent picdata){
   }
   /*
  以下为设置图片的简单方法
  protected void setImageToView(Intent data) {
    Bundle extras = data.getExtras();
    if (extras != null) {
        Bitmap photo = extras.getParcelable("data");
        photo = ImageTools.toRoundBitmap(photo, tempUri);
        iv_user_head.setImageBitmap(photo);
        ImageTools.savePhotoToSDCard(this, photo, Environment
                .getExternalStorageDirectory().getAbsolutePath(), String
                .valueOf(System.currentTimeMillis()));
    }
 }
  
  */

   /**
    * 保存裁剪之后的图片数据,由子类实现
    *
    * @param
    *
    * @param
    */
   protected void setImageToView(Uri uri){
   }
  
}
//方法较多,在此写出几个主要的,当然,对于一些代码,并没有过多解释,可以百度一下,另外如果有什么错误,还望指出,谢谢
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值