最近的项目需要做好拍照和相册选择并剪切照片的功能,实现拍照和相册选择,我首先看了第一行代码,上面有关于两个功能的实现。但是,我觉得有点繁琐,就重新写了下面的方法
我做的功能是,需要有底部弹框,选择拍照还是相册选择
底部弹框是借鉴的前辈的,网址是https://www.jianshu.com/p/2a90c3f0fbf3,我做的是仿QQ弹框,读者需要其他形式的可自取
dependencies {
compile 'com.longsh:OptionFrame:1.0.0'
}
底部弹框
List stringList = new ArrayList();
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;
然后就是在弹框中添加点击事件(分别点击拍照和从相册选择)的逻辑了,这里在上面的点击事件中具体区分了
@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;
}
}
打开相册
//打开相册
private void openAlbum() {
Intent intent_album = new Intent( Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI );
startActivityForResult( intent_album, CHOOSE_PHOTO );
}
其中不止获取图片还要剪切,下面看剪切的逻辑
//剪切图片
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 );
}
由于使用的是待返回结果的活动启动方法,故要重写下面的方法
@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;
}
}
没有图片说明,可能有点枯燥,不过这个实现也是我查了些资料采总结出来的,其中有些借鉴的网址我找不到了,如有侵权,请联系删除。