android studio实现拍照,从相册选择和剪切功能

最近的项目须要作好拍照和相册选择并剪切照片的功能,实现拍照和相册选择,我首先看了第一行代码,上面有关于两个功能的实现。可是,我以为有点繁琐,就从新写了下面的方法android

我作的功能是,须要有底部弹框,选择拍照仍是相册选择web

底部弹框是借鉴的前辈的,网址是https://www.jianshu.com/p/2a90c3f0fbf3,我作的是仿QQ弹框,读者须要其余形式的可自取ide

仿QQ弹框
在这里插入图片描述
首先加入依赖svg

dependencies {
       compile 'com.longsh:OptionFrame:1.0.0'
 }

底部弹框工具

List<String> stringList = new ArrayList<String>();
stringList.add("拍照");
stringList.add("从相册选择");
final OptionBottomDialog optionBottomDialog = new OptionBottomDialog(MainActivity.this, stringList);
optionBottomDialog.setItemClickListener(new AdapterView.OnItemClickListener() {

@Override
//点击事件
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
	//点击事件的逻辑,这里统一写成取消弹框
     optionBottomDialog.dismiss();
}

});

全局变量测试

//拍照功能参数
private static final int TAKE_PHOTO = 1;
private static final int CHOOSE_PHOTO = 2;
private final static int CROP_IMAGE = 3;

//imageUri照片真实路径
private Uri imageUri;
//照片存储
File filePath;

而后就是在弹框中添加点击事件(分别点击拍照和从相册选择)的逻辑了,这里在上面的点击事件中具体区分了ui

@Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    //取消底部弹框
                    //optionBottomDialog.dismiss();
                    switch (position) {
                        case 0:
                            //测试使用,验证是否为position= 0
                            //Toast.makeText(RegisterIn.this,"position 0", Toast.LENGTH_SHORT ).show();
                            
                            //启动相机程序
                            //隐式Intent
                            Intent intent_photo = new Intent( "android.media.action.IMAGE_CAPTURE" );
                            //putExtra()指定图片的输出地址,填入以前得到的Uri对象
                            imageUri = ImageUtils.getImageUri( RegisterIn.this );
                            intent_photo.putExtra( MediaStore.EXTRA_OUTPUT, imageUri );
                            //startActivity( intent_photo );
                            startActivityForResult( intent_photo, TAKE_PHOTO );
                            //底部弹框消失
                            optionBottomDialog.dismiss();
                            break;
                        case 1:
                            //测试使用,验证是否为position= 1
                            //Toast.makeText(RegisterIn.this,"position 1", Toast.LENGTH_SHORT ).show();
                            //打开相册
                            openAlbum();
                            //底部弹框消失
                            optionBottomDialog.dismiss();
                            break;
                        default:
                            break;
                    }
                }

打开相册this

//打开相册
private void openAlbum() {
    Intent intent_album = new Intent( Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI );

    startActivityForResult( intent_album, CHOOSE_PHOTO );
}

其中不止获取图片还要剪切,下面看剪切的逻辑code

//剪切图片
private void startImageCrop(File saveToFile,Uri uri) {
    if(uri == null){
        return ;
    }
    Intent intent = new Intent( "com.android.camera.action.CROP" );
    Log.i( "Test", "startImageCrop: " + "执行到压缩图片了" + "uri is " + uri );
    intent.setDataAndType( uri, "image/*" );//设置Uri及类型
    //uri权限,若是不加的话,   会产生没法加载图片的问题
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    intent.putExtra( "crop", "true" );//
    intent.putExtra( "aspectX", 1 );//X方向上的比例
    intent.putExtra( "aspectY", 1 );//Y方向上的比例
    intent.putExtra( "outputX", 150 );//裁剪区的X方向宽
    intent.putExtra( "outputY", 150 );//裁剪区的Y方向宽
    intent.putExtra( "scale", true );//是否保留比例
    intent.putExtra( "outputFormat", Bitmap.CompressFormat.PNG.toString() );
    intent.putExtra( "return-data", false );//是否将数据保留在Bitmap中返回dataParcelable相应的Bitmap数据,防止形成OOM,置位false
    //判断文件是否存在
    //File saveToFile = ImageUtils.getTempFile();
    if (!saveToFile.getParentFile().exists()) {
        saveToFile.getParentFile().mkdirs();
    }
    //将剪切后的图片存储到此文件
    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(saveToFile));
    Log.i( "Test", "startImageCrop: " + "即将跳到剪切图片" );
    startActivityForResult( intent, CROP_IMAGE );
}

因为使用的是待返回结果的活动启动方法,故要重写下面的方法orm

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        case TAKE_PHOTO:
            if (resultCode == RESULT_OK) {
                //须要对拍摄的照片进行处理编辑
                //拍照成功的话,就调用BitmapFactory的decodeStream()方法把图片解析成Bitmap对象,而后显示
                Log.i( "Test", "onActivityResult TakePhoto : "+imageUri );
                //Bitmap bitmap = BitmapFactory.decodeStream( getContentResolver().openInputStream( imageUri ) );
                //takephoto.setImageBitmap( bitmap );
                //设置照片存储文件及剪切图片
                File saveFile = ImageUtils.getTempFile();
                filePath = ImageUtils.getTempFile();
                startImageCrop( saveFile,imageUri );
            }
            break;
        case CHOOSE_PHOTO:
            if (resultCode == RESULT_OK) {
                //选中相册照片显示
                Log.i( "Test", "onActivityResult: 执行到打开相册了" );
                try {
                    imageUri = data.getData(); //获取系统返回的照片的Uri
                    Log.i( "Test", "onActivityResult: uriImage is " +imageUri );
                    String[] filePathColumn = {MediaStore.Images.Media.DATA};
                    Cursor cursor = getContentResolver().query(imageUri,
                            filePathColumn, null, null, null);//从系统表中查询指定Uri对应的照片
                    cursor.moveToFirst();
                    int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                    String path = cursor.getString(columnIndex);  //获取照片路径
                    cursor.close();
                    Bitmap bitmap = BitmapFactory.decodeFile(path);
                    //                        photo_taken.setImageBitmap(bitmap);
                    //设置照片存储文件及剪切图片
                    File saveFile = ImageUtils.setTempFile( RegisterIn.this );
                    filePath = ImageUtils.getTempFile();
                    startImageCrop( saveFile,imageUri );
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            break;
        case CROP_IMAGE:
            if(resultCode == RESULT_OK){
                Log.i( "Test", "onActivityResult: CROP_IMAGE" + "进入了CROP");
                // 经过图片URI拿到剪切图片
                //bitmap = BitmapFactory.decodeStream( getContentResolver().openInputStream( imageUri ) );
                //经过FileName拿到图片
                Bitmap bitmap = BitmapFactory.decodeFile( filePath.toString() );
                //把裁剪后的图片展现出来
                takephoto.setImageBitmap( bitmap );
                //ImageUtils.Compress( bitmap );
            }
            break;
        default:
            break;
    }
}

其中使用到的工具类ImageUtils

public class ImageUtils {
  private static String TAG = "Test";
  public static File tempFile;

	public static Uri getImageUri(Context content) {
    File file = setTempFile( content );
    try {
        file.createNewFile();
    } catch (IOException e) {
        e.printStackTrace();
    }
    if(Build.VERSION.SDK_INT >= 24){
        //将File对象转换成封装过的Uri对象,这个Uri对象标志着照片的真实路径
        Uri imageUri = FileProvider.getUriForFile( content, "com.example.a15927.bottombardemo.fileprovider", file );
        return imageUri;
    }else{
        //将File对象转换成Uri对象,这个Uri对象标志着照片的真实路径
        Uri imageUri = Uri.fromFile( file );
        return imageUri;
    }
 }

 public static File setTempFile(Context content) {
    //自定义图片名称
    String name = DateFormat.format("yyyyMMdd_hhmmss", Calendar.getInstance( Locale.CHINA)) + ".png";
    Log.i( TAG, " name : "+name );
    //定义图片存放的位置
    tempFile = new File(content.getExternalCacheDir(),name);
    Log.i( TAG, " tempFile : "+tempFile );
    return tempFile;
 }

 public static File getTempFile() {
    return tempFile;
 }
}

没有图片说明,可能有点枯燥,不过这个实现也是我查了些资料采总结出来的,其中有些借鉴的网址我找不到了,若有侵权,请联系删除。