赞
踩
最近的项目需要做好拍照和相册选择并剪切照片的功能,实现拍照和相册选择,我首先看了第一行代码,上面有关于两个功能的实现。但是,我觉得有点繁琐,就重新写了下面的方法
我做的功能是,需要有底部弹框,选择拍照还是相册选择
底部弹框是借鉴的前辈的,网址是https://www.jianshu.com/p/2a90c3f0fbf3,我做的是仿QQ弹框,读者需要其他形式的可自取
仿QQ弹框
首先加入依赖
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;
然后就是在弹框中添加点击事件(分别点击拍照和从相册选择)的逻辑了,这里在上面的点击事件中具体区分了
@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; } }
没有图片说明,可能有点枯燥,不过这个实现也是我查了些资料采总结出来的,其中有些借鉴的网址我找不到了,如有侵权,请联系删除。
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。