android调用原生剪裁界面裁剪图片

android调用原生剪裁界面裁剪图片

最近做一个用户上传图像的功能,本来以为很简单的,就是拍照或从相册得到图片,然后调用系统自带的裁剪功能裁剪下就可以了,但是真正写的时候发现还是有些坑的。主要的问题是裁剪时参数一定要设置对,要不然就会得不到裁剪后的图片。还有就是不管是拍照还是裁剪,最好选择将图片保存到一个临时目录,不要选择直接在intent的data中直接返回bitmap对象。

直接上代码了,下面的类中实现了从相册和拍照得到图片,并剪裁图片的功能。
代码在5.0(三星),6.0(nexus)的机器上测试是没有问题的,如果大家发现有什么问题欢迎留言指正。

/**
 * Created by lee on 2016/9/19.
 */
public class ImageUploadFragment extends Fragment {

    private ImageView headView;
    private View rootView;
    private static final int REQUEST_CODE_SELECT_PHOTO = 1;
    private static final int REQUEST_CODE_TAKE_PHOTO = 2;
    private static final int REQUEST_CODE_CUT_PHOTO = 3;
    private String IMAGE_NAME = "temp.jpeg";
    private String IMAGE_FILE_URI_PATH = "";

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.fragment_image_upload, container, false);
        return rootView;
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        headView = (ImageView) rootView.findViewById(R.id.image);
        headView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showChooseImageDialog();
            }
        });
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        IMAGE_FILE_URI_PATH = getActivity().getExternalCacheDir().getPath();
    }

    private void showChooseImageDialog() {
        CharSequence[] items = {"相册", "相机"};
        new AlertDialog.Builder(getActivity())
                .setTitle("选择图片来源")
                .setItems(items, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        if (which == 0) {
                            chooseImg();
                        } else {
                            takePhoto();
                        }
                    }
                })
                .create().show();
    }

    private void takePhoto() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, getTempPhotoFileUri());
        startActivityForResult(intent, REQUEST_CODE_TAKE_PHOTO);
    }

    private void chooseImg() {
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_PICK);//Pick an item from the data
        intent.setType("image/*");//从所有图片中进行选择
        startActivityForResult(intent, REQUEST_CODE_SELECT_PHOTO);
    }

    private Uri getTempPhotoFileUri() {
        File file = new File(IMAGE_FILE_URI_PATH);
        if (!file.exists()) {
            file.mkdirs();
        }
        File imageFile = new File(file, IMAGE_NAME);
        return Uri.fromFile(imageFile);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == Activity.RESULT_OK) {
            if (requestCode == REQUEST_CODE_SELECT_PHOTO) {
                if (data != null) {
                    Uri uri = data.getData();
                    crop(uri, getTempPhotoFileUri());
                }
            } else if (requestCode == REQUEST_CODE_TAKE_PHOTO) {
                crop(getTempPhotoFileUri(), getTempPhotoFileUri());
            } else if (requestCode == REQUEST_CODE_CUT_PHOTO) {
                handleCropImg(data);
                try {
                    deleteFile(getTempPhotoFileUri().getPath());
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }

        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    private void handleCropImg(Intent data) {
        if (data != null) {
            //有的手机返回的data中没有任何数据,可能和crop时Intent中使用了MediaStore.EXTRA_OUTPUT有关,所以直接从保存图片的uri中获取图片
//            Uri uri = data.getData();
            Bitmap bitmap = getBitmapFromUri(getTempPhotoFileUri());
            if (bitmap != null) {
                headView.setImageBitmap(bitmap);
            }
        }
    }

    public Bitmap getBitmapFromUri(Uri uri) {
        try {
            // 读取uri所在的图片
            Bitmap bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), uri);
            return bitmap;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 剪切图片
     *
     * @param uri 原始图片的uri
     */
    private void crop(Uri uri, Uri tempPhotoUri) {
        // 裁剪图片意图
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        intent.putExtra("crop", "true");//设置为裁切
        intent.putExtra("aspectX", 1);//裁切的宽比例
        intent.putExtra("aspectY", 1);//裁切的高比例
        intent.putExtra("outputX", 250);//裁切的宽度
        intent.putExtra("outputY", 250);//裁切的高度
        intent.putExtra("scale", true);//支持缩放
        intent.putExtra("return-data", false);//剪切的图片不直接返回,返回uri,否则6.0可能会返回null
        //这里是剪切后图片保存的文件地址,加了这行,可能有些手机返回的intent是空的,所以最好直接使用这个uri获取剪切后的图片
        intent.putExtra(MediaStore.EXTRA_OUTPUT, tempPhotoUri);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());//裁切成的图片的格式
        intent.putExtra("noFaceDetection", true); // no face detection
        startActivityForResult(intent, REQUEST_CODE_CUT_PHOTO);
    }

    private boolean deleteFile(String filepath) {
        boolean wasDeleted = false;
        try {
            File file = new File(filepath);
            wasDeleted = file.delete();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return wasDeleted;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值