博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 拍照或相册剪裁后取头像
阅读量:6949 次
发布时间:2019-06-27

本文共 10676 字,大约阅读时间需要 35 分钟。

引用

1、

2、联合使用:

截图

img_ebf2ee94263dd072379906b088e90166.png
crop_img.png
img_029c5172c3e3d263bf2c1de7afef04a0.png
croping.png

实现

1、功能步骤
  • 1.1、相机和相册使用到的权限
  • 1.2、打开相机、打开相册
  • 1.3、相机拍照回调、相册选取回调
  • 1.4、两种不同方式回调后的uri使用并开启剪裁
  • 1.5、剪裁图片回调、展示图片(各种样式)
  • 1.6、其他注意:android 7.0 后的共享文件FileProvider配置等
2、工具类
  • 2.1、此工具类不一定符合所有业务,可自行扩展或者弄成接口类来完成各种功能
  • 2.2、使用相机:注意android 7.0的fileprovider来获取uri,完成拍照存储
  • 2.3、使用相册:注意ACTION_PICK和ACTION_GET_CONTENT的区别,并在不同api下返回的uri值不一样导致“无法加载图片”的问题,代码中写了注释
  • 2.4、相机图片剪裁:注意要加上intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);作为图片来源加载在剪切图中
  • 2.5、相册图片剪裁:不用加【2.4】内容
  • 2.6、剪裁输出源:可直接intent.putExtra("return-data", true);返回直接是bitmap有可能导致oom,还是设置false,然后靠uri来指向输出源比较好
/** * Created by wujn on 2018/10/31. * Version : v1.0 * Function: crop photo by camera or album */public class CropPhotoHelper {    private Activity instance;    // 裁剪后图片的宽(X)和高(Y),320 X 320的正方形。    private static int output_X = 480;    private static int output_Y = 480;    private String localUserImgName ;       //原始拍照图片    private String localUserImgPath;    private Uri takePhotoUri;               //拍照的uri    private String localUserCropImgName;    //最后的剪裁图片    private String localUserCropImgPath;    private Uri localUserIconUri;           //用户头像图片uri    private String parentDir;               //父目录    public CropPhotoHelper(Activity instance, String localUserImgName, String localUserCropImgName, String parentDir){        this.instance = instance;        this.localUserImgName = localUserImgName;        this.localUserImgPath = parentDir + localUserImgName;        this.localUserCropImgName = localUserCropImgName;        this.localUserCropImgPath = parentDir + localUserCropImgName;        this.parentDir = parentDir;    }    /**     * 拍照     * uri = content://.fileprovider/external_storage_root/xxx/xxx.jpg     * */    public void takePhoto(boolean isDeleteOld, int requestCode){        FileUtil.mkDir(parentDir);        File tmpFile=new File(localUserImgPath); //固定的,用户图片        //删除旧的        if (isDeleteOld) {            try {                if (tmpFile.exists()) {                    tmpFile.delete();//删除                }                tmpFile.createNewFile();            } catch (Exception e) {                e.printStackTrace();            }        }        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {            takePhotoUri = Uri.fromFile(tmpFile);        }else{            takePhotoUri = FileProvider.getUriForFile(instance, Constant.FileProviderValue, tmpFile);        }        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);        intent.putExtra(MediaStore.EXTRA_OUTPUT, takePhotoUri);        //intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);        //intent.putExtra(MediaStore.Images.Media.ORIENTATION, 0);        //intent.putExtra("aspectX", 4);        //intent.putExtra("aspectY", 3);        //intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 120 * 1024);        //intent.putExtra("return-data", true);        instance.startActivityForResult(intent, requestCode);    }    /**     * 打开相册     * 1、Intent.ACTION_PICK,null :     * uri=content://media/external/images/media/86916     *     * 2、Intent.ACTION_GET_CONTENT :     *   (1)<=4.3 : uri 返回的是带文件路径的     *   (2)>4.3 : uri 返回content://com.android.providers.media.documents/document/image:3951     *       这样的,没有路径,只有图片编号的uri.这就导致接下来无法根据图片路径来裁剪的步骤了.     * */    public void openAlbum(int requestCode){        //method 1//        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);//        intent.setType("image/*");        //method 2        Intent intent = new Intent(Intent.ACTION_PICK);        //intent.setType("image*//*");        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");        instance.startActivityForResult(intent,requestCode);//打开相册    }    /**     * 从相机拍照的图片剪裁     * */    public void cropRawByCamera(int requestCode){        LogUtil.i("cropRawByCamera inputUri="+ takePhotoUri.toString());        Intent intent = getCropImgIntent();        //输入原始图片:来源于拍照        if(takePhotoUri != null){            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);            intent.setDataAndType(takePhotoUri, "image/*");        }        instance.startActivityForResult(intent, requestCode);    }    /**     * 从相册图片剪裁     * */    public void cropRawByAlbum(Uri inputUri, int requestCode){        LogUtil.i("cropRawByAlbum inputUri="+ inputUri.toString());        Intent intent = getCropImgIntent();        //输入原始图片:来源于相册        if(inputUri != null){            //intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)            intent.setDataAndType(inputUri, "image/*");        }        instance.startActivityForResult(intent, requestCode);    }    /**     * 裁剪原始的图片意图     */    private Intent getCropImgIntent(){        //剪裁action        Intent intent = new Intent("com.android.camera.action.CROP");        // 设置裁剪        intent.putExtra("crop", "true");        // aspectX , aspectY :宽高的比例        intent.putExtra("aspectX", 1);        intent.putExtra("aspectY", 1);        // outputX , outputY : 裁剪图片宽高        intent.putExtra("outputX", output_X);        intent.putExtra("outputY", output_Y);        intent.putExtra("scale",true);        // 返回类型和文件指向        // return data is bitmap , maybe oom        //intent.putExtra("return-data", true);             //返回bitmap        intent.putExtra("return-data", false);  //返回uri        //输出剪裁图片        File cropFile = new File(localUserCropImgPath);        try {            if (cropFile.exists()){                cropFile.delete();//删除            }            cropFile.createNewFile();        } catch (Exception e) {            e.printStackTrace();        }        localUserIconUri = Uri.fromFile(cropFile);        if (localUserIconUri != null) {            //intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);            intent.putExtra(MediaStore.EXTRA_OUTPUT, localUserIconUri);        }        //取消人脸识别        intent.putExtra("noFaceDetection", true);        //压缩图片        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());        return intent;    }    /**     * 获取剪切后的bitmap     * */    public Bitmap getCropBitmap(){        try {            return BitmapFactory.decodeStream(instance.getContentResolver().openInputStream(localUserIconUri));        } catch (FileNotFoundException e) {            e.printStackTrace();            return null;        }    }    //获取剪裁后的路径    public String getLocalUserCropImgPath() {        return localUserCropImgPath;    }}
3、使用
  • 3.1、各种回调请求的code
/**     * 权限访问请求code     * */    public static final int REQUEST_PERMISSION_CODE = 1;    public static final int REQUEST_PERMISSION_CODE_1 = 2;    /**     * ActivityResult回调的请求code     * */    public static final int REQUEST_TACKPIC_CODE = 10001;           //相机    public static final int REQUEST_CHOOSE_PHOTO_CODE = 10002;      //相册    public static final int REQUEST_CROP_IMAGE_CODE = 10003;        //剪裁图片
  • 3.2、使用相机和相册的权限询问
  • 3.3、按照【1】所说的步骤来使用
  • 3.4、图片最后使用了AvatarImageView来加载图片,这个剪裁图片加载就不再这里写了,可以使用的方法巨多...
//剪裁帮助类    private CropPhotoHelper cropPhotoHelper;    @BindView(R.id.avatar_img) AvatarImageView avatar_img;    @Override    protected void init() {        //剪裁帮助类:原始图片,剪裁图片,父目录        cropPhotoHelper = new CropPhotoHelper(instance,                "img_org.jpg",                "img_crop.jpg",                Constant.IMG_DIR);    }    //拍照取图    public void OnSelectCamera(View v){        if (EasyPermissions.hasPermissions(instance, permissions_camear)) {            cropPhotoHelper.takePhoto(false, Constant.REQUEST_TACKPIC_CODE);        }else{            EasyPermissions.requestPermissions(instance, "App 运行需要获取权限",Constant.REQUEST_PERMISSION_CODE, permissions_camear);        }    }    //相册取图    public void OnSelectAlbum(View v){        if (EasyPermissions.hasPermissions(instance, permissions_album)) {            cropPhotoHelper.openAlbum(Constant.REQUEST_CHOOSE_PHOTO_CODE);        }else{            EasyPermissions.requestPermissions(instance, "App 运行需要获取权限",Constant.REQUEST_PERMISSION_CODE_1, permissions_album);        }    }    @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        if (resultCode == RESULT_OK) {            switch (requestCode) {                //拍照回调                case Constant.REQUEST_TACKPIC_CODE:                    LogUtil.d("take picture success");                    cropPhotoHelper.cropRawByCamera(Constant.REQUEST_CROP_IMAGE_CODE);                    break;                //选择照片回调                case Constant.REQUEST_CHOOSE_PHOTO_CODE:                    LogUtil.d("choose picture success");                    if (data != null) {                        //不同api下获取相册图片的path                        //String photoPath = AppUtil.getPhotoPath(instance, data);                        cropPhotoHelper.cropRawByAlbum(data.getData(),Constant.REQUEST_CROP_IMAGE_CODE);                    } else {                        ToastUtil.showShort(instance,"相册无返回值!");                    }                    break;                //剪裁完                case Constant.REQUEST_CROP_IMAGE_CODE:                    Bitmap bitmap = cropPhotoHelper.getCropBitmap();                    if(bitmap != null){                        avatar_img.setBitmap(bitmap);                    }else{                        ToastUtil.showShort(instance,"剪裁失败!");                    }                    break;                default:                    break;            }        }    }    //=============================================权限部分=====================================================    //相机权限    private String[] permissions_camear = {            Manifest.permission.WRITE_EXTERNAL_STORAGE,            Manifest.permission.CAMERA    };    //文件权限    private String[] permissions_album = {            Manifest.permission.WRITE_EXTERNAL_STORAGE    };    @Override    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {        super.onRequestPermissionsResult(requestCode, permissions, grantResults);        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);    }    @Override    public void onPermissionsGranted(int requestCode, @NonNull List
perms) { LogUtil.i("onPermissionsGranted requestCode="+requestCode); if(Constant.REQUEST_PERMISSION_CODE == requestCode){ cropPhotoHelper.takePhoto(false, Constant.REQUEST_TACKPIC_CODE); } else if(Constant.REQUEST_PERMISSION_CODE_1 == requestCode){ cropPhotoHelper.openAlbum(Constant.REQUEST_CHOOSE_PHOTO_CODE); } } @Override public void onPermissionsDenied(int requestCode, @NonNull List
perms) { DialogUtil.errorDialog(instance,"拒绝开启,请前往APP应用设置中打开此权限"); }
哈哈,朝CV工程师在进一步!!!!

转载地址:http://houil.baihongyu.com/

你可能感兴趣的文章
reverse() ; sort() ; sorted()
查看>>
Finalize/Dispose资源清理模式
查看>>
封装dialog弹窗
查看>>
使用synchronized(非this对象)同步代码块解决脏读问题
查看>>
Oracle中使用批处理文件批量建表
查看>>
Intel笔记本低压版CPU性能对比分析
查看>>
Gephi可视化(二)——Gephi Toolkit叫板Prefuse
查看>>
Fiddler环境配置教程
查看>>
第二阶段冲刺报告
查看>>
Vue.js 系列教程 5:动画
查看>>
WinForm 使用 HttpUtility
查看>>
Zabbix QQ报警配置
查看>>
2016.8.7 UnicodeEncodeError 同时遍历多个list
查看>>
基础 网络架构 网络硬件名词 网络通信协议
查看>>
sqlite
查看>>
关于Retinex图像增强算法的一些新学习。
查看>>
一道容易栽坑的有趣的面试题(关于js,定时器,闭包等)
查看>>
正则表达式,时间戳和日期互相转换
查看>>
mysql复制(高可用架构方案的基础)
查看>>
搭建自己的OwnCloud私有云
查看>>