Android拍照和相册+系统裁剪功能返回图片

最近在使用一加3手机,Android系统6.0,进行测试的时候,发现调用手机的拍照和相册选择图片的功能返回的时候都无法调用系统的裁剪功能,Log日志也没有输出有用的信息。经过在网上大量的查找资料,拍照的问题解决了,但是用网上提供的方法都无法进行相册选择图片后进行裁剪。

测试的时候使用一加手机拍照,拍出来的照片居然能达到10M~~15M,照片太大了,用intent.getParcelableExtra("data")方法获取图片的时候OOM了,所以这里我指定了一个具体的File文件来存储拍照返回的图片,设置MediaStore.EXTRA_OUTPUT

    // 调用系统相机
    protected void startCamera() {
        // 调用系统的拍照功能
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra("camerasensortype", 2); // 调用前置摄像头
        intent.putExtra("autofocus", true); // 自动对焦
        intent.putExtra("fullScreen", false); // 全屏
        intent.putExtra("showActionIcons", false);
        // 指定调用相机拍照后照片的存储路径
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(tempFile));
        startActivityForResult(intent, PHOTO_CARMERA);
    }

tempFile为指定的File文件,在onActivityResult中通过Uri对图片进行裁剪
    @Override
    public void onActivityResult(int requestCode, int responseCode, Intent data) {
        switch (requestCode) {
            case PHOTO_CARMERA:
                startPhotoZoom(300);// 拍照返回后裁剪
                break;
            case PHOTO_PICK:
                copyFile(data);// 图库选择图片后进行裁剪
                break;
            case PHOTO_CUT:
		decodeUriAsBitmap(Uri.fromFile(tempFile));// 获取bitmap
                break;
            default:
                break;
        }
    }
调用系统的图片裁剪
 
  
    /**
     * 调用裁剪功能
     *
     * @param size
     */
    private void startPhotoZoom(int size) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(Uri.fromFile(tempFile), "image/*");
        intent.putExtra("crop", "true");
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        intent.putExtra("outputX", size);
        intent.putExtra("outputY", size);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(tempFile));
        intent.putExtra("return-data", false);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.PNG.toString());
        startActivityForResult(intent, PHOTO_CUT);
    }
通过Uri去获取裁剪后的图片
    /**
     * 通过URI获取Bitmap
     * @param uri
     * @return
     */
    private Bitmap decodeUriAsBitmap(Uri uri) {
        Bitmap bitmap = null;
        try {
            bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return null;
        }
        return bitmap;
    }
这样拍照算是解决了,但是相册选择图片后想通过调用startPhotoZoom方法进行图片的裁剪,在一加手机上总是提示"图片加载时出错",在三星,华为上都可以,唯独一加手机不可以。看了看简书APP的头像上传功能,发现这个APP在一加上是可以进行相册-->裁剪的,但是选择的图片比较大的时候,比如,3M、4M以上的图片,也是直接就返回了原来页面。
 
  
打开相册:
    // 调用系统相册
    protected void startPick() {
        Intent intent = new Intent(Intent.ACTION_PICK, null);
        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                "image/*");
        startActivityForResult(intent, PHOTO_PICK);
    }

在一加手机上选中图片返回后,没办法直接对图片进行裁剪,这时候我试着通过Uri得到选中图片的绝对路径,把该图片复制到tempFile文件中,复制完成后再调用startPhotoZoom方法进行裁剪
 
  
获取相册选中图片路径并且复制到指定文件夹中
    /**
     * 处理相册选择图片后无法裁剪
     * 将选中的图片写入到目标文件中
     * 将目标文件的path作为裁剪的URI
     * @param data
     */
    private void copyFile(final Intent data){
        showProgressDialog("");
        new Thread(new Runnable() {
            @Override
            public void run() {
                Uri selectedImage = data.getData(); //获取系统返回的照片的Uri
                String picturePath = "";// 相册中的文件路径
                String[] filePathColumn = { MediaStore.Images.Media.DATA };
                Cursor cursor =getContentResolver().query(selectedImage,
                        filePathColumn, null, null, null);//从系统表中查询指定Uri对应的照片
                if(null != cursor){
                    cursor.moveToFirst();
                    int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                    picturePath = cursor.getString(columnIndex);  //获取照片路径
                    cursor.close();
                }else{
                    picturePath = selectedImage.getPath();
                }
                try {
                    if(!tempFile.exists()){
                        tempFile.createNewFile();
                    }
                    InputStream fosfrom = new FileInputStream(new File(picturePath));
                    OutputStream fosto = new FileOutputStream(tempFile);
                    byte bt[] = new byte[1024];
                    int c;
                    while ((c = fosfrom.read(bt)) > 0)
                    {
                        fosto.write(bt, 0, c);
                    }
                    fosfrom.close();
                    fosto.flush();
                    fosto.close();
                    mHandler.sendEmptyMessage(COPY_FILE_COMPLETE);
                } catch (Exception e) {
                    e.printStackTrace();
                    mHandler.sendEmptyMessage(NO_PHOTO);
                }
            }
        }).start();
    }

COPY_FILE_COMPLETE完成后,在Handler中调用startPhotoZoom方法进行裁剪。经过测试,这个方法可行,唯一不好的地方是多了一步复制文件的操作......
 
  
哪位大神有更好的方法,希望多多指教,不胜感激!



 
  
 
  
 
  
 
  
 
  
 
  

你可能感兴趣的:(Android)