Android拍照及裁剪实现

一.概述

拍照以及裁剪功能在有些项目中还是经常能遇到的,一般而言,使用拍照和裁剪功能基本上都是使用系统自带的Intent来实现,看起来很简单,但是其中还是有一些问题需要注意的。
这里我们要实现一个功能,点击Button启动系统相机,拍照后将照片显示到按钮下方的ImageView中。

二.基本知识讲解

先看看拍照和裁剪对应的动作;
拍照:
MediaStore.ACTION_IMAGE_CAPTURE
裁剪:
com.android.camera.action.CROP

下面看一下裁剪时用的一些参数:

这些参数是选择性的使用的,可以根据你的需求来选择,这些参数里面,
我重点讲一下return-data,MediaStore.EXTRA_OUTPUT这两个参数。
return-data:这里我会将这个参数一直设置为false,因为如果设置为true,就无法将得到的图片设置给我们的ImageView了,所以我们使用Uri来输出。

1.仅拍照

首先因为我们要使用sd卡路径,所以先添加权限:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/

然后构建一个图片地址的Uri:

imageuri = Uri.fromFile(createImageFile(".jpg"));

下面是创建Uri的方法的代码:

  private File createImageFile(String prefix) {
        File image = null;
        String timeStamp = new SimpleDateFormat("yyyy_MM_dd_hh_MM_ss")
                .format(new Date());
        String imageName = prefix+"_JPEG_" + timeStamp + "_";
        File imageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        try {
            image = File.createTempFile(imageName, ".jpg", imageDir);
        } catch (IOException e) {
            image = null;
            e.printStackTrace();
        }
        return image;
    }

然后通过Intent来启动照相机,设置参数:

Intent intent = null; 
intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
intent.putExtra("return-data", false); 
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); 
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); 
intent.putExtra("noFaceDetection", true); 
startActivityForResult(intent, ACTION_TAKE);

大家可能对return-data和MediaStore.EXTRA_OUTPUT的作用有些迷糊;

return-data:是将结果保存在data中返回,在onActivityResult中,直接调用intent.getdata()就可以获取值了,这里设为fase,就是不让它保存在data中,

MediaStore.EXTRA_OUTPUT:由于我们不让它保存在Intent的data域中,但我们总要有地方来保存我们的图片啊,这个参数就是转移保存地址的,对应Value中保存的URI就是指定的保存地址。

在onActivityResult()中接收:

  @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode!= Activity.RESULT_OK){
            Toast.makeText(this, "失败", Toast.LENGTH_SHORT).show();
            return;
        }
        switch (requestCode){
            case ACTION_TAKE:
               Bitmap bitmap =   BitmapFactory.decodeStream(getContentResolver().openInputStream(bitmap));
                    imageView.setImageBitmap(bitmap);
                break;
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                break;
        }

我们接收到Bitmap以后设置给ImageView,但是在有的手机上并不会显示出来,我们去看目录下的文件的确实产生了,那为什么会不显示呢,因为图片太大了,超出ImageView的显示范围。所以一般如果要显示的话,需要裁剪一下。

2。拍照并裁剪

首先声明两个Uri,一个保存拍照的结果,一个保存裁剪的结果:

 imageuri = Uri.fromFile(createImageFile("jpg"));
        cropuri = Uri.fromFile(createImageFile("temp"));

点击按钮时仅调起拍照Intent,将结果存在imageUri中

Intent intent = null; 
intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
intent.putExtra("return-data", false); 
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); 
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); 
intent.putExtra("noFaceDetection", true); 
startActivityForResult(intent, ACTION_TAKE);

在接收到返回的消息后,调起裁剪Intent:

   @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode!= Activity.RESULT_OK){
            Toast.makeText(this, "失败", Toast.LENGTH_SHORT).show();
            return;
        }
        switch (requestCode){
            case ACTION_TAKE:
                cropImage(imageuri);
                break;
        }
    }
  public void cropImage(Uri uri){
        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", 700);
        intent.putExtra("outputY", 700);
        intent.putExtra("return-data", false);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, cropuri);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true);
        startActivityForResult(intent, ACTION_CROP);
    }

将传进去的uri做为源数据,即被裁剪的数据,将结果存储在imageCropUri中,最后在onActivityResult中接受:

  @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode!= Activity.RESULT_OK){
            Toast.makeText(this, "失败", Toast.LENGTH_SHORT).show();
            return;
        }
        switch (requestCode){
            case ACTION_TAKE:
                cropImage(imageuri);
                break;
            case ACTION_CROP:
                try {
                  Bitmap bitmap =   BitmapFactory.decodeStream(getContentResolver().openInputStream(cropuri));
                    imageView.setImageBitmap(bitmap);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                break;
        }
    }

这样就可以正常将结果显示到ImageView了

你可能感兴趣的:(Android拍照及裁剪实现)