android图片的处理及剪裁

来源:互联网 发布:穆雅斓淘宝店是正品 编辑:程序博客网 时间:2024/04/29 09:07

     作为android开发的新手,前阵子做了个关于图片处理和剪裁的demo;参考了网上的一些 资料,结合了自身的一些理解,于是就过来发表下新的,顺便也给这个知识点做下总结,让很多新手可以少走些弯路,当然文章中可能也有些不足,也希望大家指出,共同进步^ ^!
  图片的获得一般就是从相册中获取和拍照,我们先来说说从相册中获取。最基本的调用系统图库:

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

startActivityForResult(intent, REQUEST_CODE_IMAGE);

     但是经过测试会发现加载的图片如果过大就会出现OOM(不知道的小伙伴请自行百度^^),所以就要把图片临时储存在文件夹中在调用显示就可以了,拍照取得的图片也是一样,为了防止OOM也要用相同的处理方法:

Intent Intent = new Intent(Intent.ACTION_PICK, new Intent(Intent.ACTION_PICK, null);Intent.setType("image/*");//从所有图片中进行选择Intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());//把图片转成JPEG形式保存Intent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri());
private Uri getTempUri() {   return Uri.fromFile(getTempFile());}private File getTempFile() {   if (Environment.getExternalStorageState().equals(         Environment.MEDIA_MOUNTED)) {      File file = new File(Environment.getExternalStorageDirectory(),            Constants.TEMP_PHOTO_FILE);      try {         file.createNewFile();      } catch (IOException e) {         e.printStackTrace();      }      return file;   } else {      return null;   }}
拍照时:

try {   getGoodsImageMethodChooser.dismiss();   Intent intentFromCapture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);   intentFromCapture.putExtra(Constants.OUTPUT_FORMAT, Bitmap.CompressFormat.JPEG.toString());   intentFromCapture.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0);   File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);   File tempFile = new File(path, Constants.TEMP_PHOTO_FILE);   // 判断存储卡是否可以用,可用进行存储   intentFromCapture.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(tempFile));   startActivityForResult(intentFromCapture, CAMERA_REQUEST_CODE);} catch (Exception e) {}
返回时:

/** * 返回 */@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {   super.onActivityResult(requestCode, resultCode, data);   if (resultCode != RESULT_CANCELED && requestCode == IMAGE_REQUEST_CODE) {    handleImage(data.getData());// 手机相册返回   }   if (resultCode != RESULT_CANCELED && requestCode == CAMERA_REQUEST_CODE) {      File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);      File tempFile2 = new File(path, Constants.TEMP_PHOTO_FILE);      Bitmap bitmap =decodeUriAsBitmap(Uri.fromFile(tempFile2));      handleImage(bitmap);// 拍照返回   }}
需要注意的是在把图片放到ImageView中的时候要用setImageBitmap()这个方法,而不要用setImageURL的方法,因为效率不一样而且在加载某些大图片时setImageURL方法在某些机型可能有问题。

       再来说说图片剪裁,其实是差不多的,就是多了一个剪裁的步凑而已:

/** * 裁剪图片方法实现 * * @param uri */public void startPhotoZoomCertificate(Uri uri) {   /*    * 至于下面这个IntentACTION是怎么知道的,大家可以看下自己路径下的如下网页    * yourself_sdk_path/docs/reference/android/content/Intent.html    */   try {      Intent intent = new Intent("com.android.camera.action.CROP");      intent.setDataAndType(uri, "image/*");      // 下面这个crop=true是设置在开启的Intent中设置显示的VIEW可裁剪       intent.putExtra("crop", "true");      // aspectX aspectY 是宽高的比例       intent.putExtra("aspectX", 16);      intent.putExtra("aspectY", 9);      // outputX outputY 是裁剪图片宽高       intent.putExtra("outputX", 800);      intent.putExtra("outputY", 450);        intent.putExtra("outputFormat",            Bitmap.CompressFormat.JPEG.toString());      intent.putExtra("noFaceDetection", true);      intent.putExtra(MediaStore.EXTRA_OUTPUT, uritempFile);      intent.putExtra("return-data", false);// 设置为不返回数据      startActivityForResult(intent, 3);   } catch (Exception e) {   }} 
//uritempFile是剪裁保存的路径 可以自己定义,我把它定义成这样
private Uri uritempFile = Uri.parse("file://" + "/"      + Environment.getExternalStorageDirectory().getPath() + "/"      + "small.jpg");
在返回时写成这样:

/** * 返回 */@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {   super.onActivityResult(requestCode, resultCode, data);   if (resultCode != RESULT_CANCELED && requestCode == IMAGE_REQUEST_CODE) {    startPhotoZoomCertificate(data.getData());// 手机相册返回   }   if (resultCode != RESULT_CANCELED && requestCode == CAMERA_REQUEST_CODE) {      File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);      File tempFile2 = new File(path, Constants.TEMP_PHOTO_FILE);      Bitmap bitmap =decodeUriAsBitmap(Uri.fromFile(tempFile2));      startPhotoZoomCertificate(Uri.fromFile(tempFile2));// 拍照返回   } 
       if (requestCode == 3&& resultCode==RESULT_OK) { //&& data != null         Bitmap bitmap = null;         try {//          BitmapFactory.Options options = new BitmapFactory.Options();//          options.inSampleSize = 2;//BitmapFactory.decodeStream压缩图片的方法//          bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uritempFile),null,options);            bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uritempFile));         } catch (FileNotFoundException e) {            e.printStackTrace();         }            if (bitmap != null) {               handleImage(bitmap);            }      }   }
public void handleImage(Bitmap photo) {   goodsImage = photo;// decode bitmap   goodsImageButton.setImageBitmap(photo);   //goodsImageButton就是我们定义的ImageView了
}
      图片的选择和剪裁大概就是这样了,本人比较懒,所以原理什么的都没详说,大家不懂的自己百度下吧^ ^。其实这样写完一般情况下是没问题的,但是android现在碎片化这么严重,有些记机子的剪裁会有问题,如果你装过QQ游览器等软件,在从系统相册选取图片时,可能也会出现拿不到图片的情况!什么?那呢?老子裤子都脱了,看完文章,你竟然说有问题!!!骂人不要慌,其实对于android的图片选择和剪裁,其实还是用第三方架包比较靠谱,在GitHub上有很多优秀的架包可以用(当然你牛逼到自己可以写当我没说);这里就好人做到底把我辛辛苦苦找的架包和大家分享下吧大笑

图片剪裁

uCrop 

:项目地址https://github.com/Yalantis/uCrop  项目目标是提供终极的,灵活的图片剪裁,但是个人认为功能太多了,太耗内存,低端机跑起来会很卡,而且有些功能对于只需要剪裁功能的根本没必要。
android-crop:项目地址https://github.com/jdamcd/android-crop 没有uCrop这么多功能 简简单单,就是剪裁的功能(本人就是用这个架包的)。
图片选择
MultilmageSelector:项目地址https://github.com/lovetuzitong/MultiImageSelector   是个高仿微信朋友圈的图片选择的工具库,大家可以试试。
最后谢谢大家,有问题可以留言,大家一起进步^ ^..





0 0