Android获取图片并裁剪
2015-12-09 20:05
225 查看
手机获取图片两种方式
通过相机拍照从系统图库中选取
基本流程
无论是选择拍照还是选择现成的图片进行裁剪,都要分为以下三个步骤:S1. 调用系统的拍照界面或者图库的管理界面,由于我们要对该界面的操作结果进行监听,因此我们在启动Activity的时候使用
startActivityForResult(Intent intent, int requestCode)函数。假设我们在界面
A1中用
startActivityForResult的方式启动界面
A2,那么当
A2关闭之后,会自动调用
A1的
onActivityResult函数(因此我们需要重写该函数)
S2. 在
onActivityResult(int requestCode, int resultCode, Intent data)函数中,data中包含被关闭的界面(
A2)传递过来的数据,所以我们需要的”被选择的图片“或者”拍照生成的图片“信息就包含在这个里面,此时我们就可以在这个操作的基础之上接着进行图片的裁剪操作,同样是调用系统的界面,同样是使用
startActivityForResult的方式
S3. 最后还是一样,在
onActivityResult中我们可以得到图片裁剪界面回传过来的intent的对象,里面就包含了裁剪过的图片的数据,我们获取数据,接下来的操作就自定义了
还好系统给我们提供了很多现成的操作界面,所以功能实现起来并不太复杂
准备工作
在使用startActivityForResult需要传入一个名为
requestCode的参数,在
onActivityResult函数中我们还会获得一个名为
resultCode的参数,这个具体可以这么来解释:
对于一个界面
A1,我们可以通过
startActivityForResult的方式来启动很多个界面
A2、
A3…,那么在
onActivityResult函数中就会有一个疑问了:这个函数到底是因为我们启动的
A2、
A3…哪个界面被关闭而调用的呢?
所以这时,就是
requestCode发挥作用的时候了,通过它来区分不同的启动界面,让我们知道到底是
A2、
A3…中的哪个界面关闭后传递数据过来,这样我们就不会产生歧义了。
而
resultCode顾名思义就能知道是界面的执行结果代码,就比如在选择图片时,正常的流程当然是用户点击了一个图片然后返回,可是如果用户按下了键盘上的Back键,这时候我们怎么能做出正确的相应操作?只有通过这个参数,它可能的取值有
Activity.RESULT_OK、
Activity.RESULT_CANCELED等等,这样就能帮助我们做出正确的判断了。
所以就我们第一步就是先要区分一下拍照界面和图库选择界面,我们在类中定义:
[code]final int REQUEST_CAPTURE = 1; //表示拍照界面 final int REQUEST_SELECT = 2; //表示图库选择界面 final int REQUEST_CROP = 3; //表示图片裁剪界面
由拍照获取图片
进入拍照界面很简单,代码如下:[code]Intent intent = new Intent(); intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent, REQUEST_CAPTURE);
从图库选择图片
[code]Intent intent = new Intent(); //"image/*"表示通配所有图片类型的文件,包含"image/png"、"image/jpeg"等 intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(intent, REQUEST_SELECT);
上述代码中为什么不是
intent.setAction(Intent.ACTION_PICK)?
图片裁剪
这一步是建立在前面的图片获取基础之上,我们需要重写Activity中的
onActivityResult函数,代码如下:
[code]@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { //操作失败,用户没有拍照成功或者没有选择图片时 if (Activity.RESULT_OK != resultCode) { return ; } switch (requestCode) { //拍照 case REQUEST_CAPTURE: //从图库中选择 case REQUEST_SELECT: { //启动裁剪界面 Intent intent = new Intent("com.android.camera.action.CROP"); intent.putExtra("crop", "true"); intent.putExtra("scale", true); intent.putExtra("noFaceDetection", true); //裁剪图片的长宽比 intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); //裁剪图片的输出大小 intent.putExtra("outputX", 512); intent.putExtra("outputY", 512); //这里我们不把图片以Bitmap形式进行返回,因为数据量过大 //我们将裁剪后生成的图片保存到本地 intent.putExtra("return-data", false); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File("裁剪输出文件路径")); //设置需要裁剪的图片数据 intent.setDataAndType(data.getData(), "image/*"); startActivityForResult(intent, REQUEST_CROP); } break; //裁剪图片结果 case REQUEST_CROP: { // TODO what you wanna do... // 裁剪生成的图片在上述代码中的"裁剪输出文件路径"位置 } break; default: break; } }
可能出现的问题
到这里似乎看起来就大功告成了,然而部分手机的运行结果可能事与愿违,如小米4,在执行拍照返回之后进行裁剪,发现漆黑一片,没有图片,究其原因,是在上述代码中null == data.getData()导致的。
解决办法如下:
[code]//在启动拍照界面之前添加 //就相当于我们要把拍照生成的图片保存到一个我们自定义的路径中 //在要进行裁剪操作,我们再把这个自定义的路径以Uri的形式传递过去以便找到 File img = new File("拍照图片临时保存路径"); if (img.exists()) { img.delete(); } try { img.createNewFile(); } catch (IOException e) { e.printStackTrace(); } intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(img));
同时将上述
onActivityResult函数中的:
[code]intent.setDataAndType(data.getData(), "image/*");
修改为:
[code]intent.setDataAndType(Uri.fromFile(new File("拍照图片临时保存路径"), "image/*");
用这种方式的好处就相当于我们不用在信息交换中携带大量的原始数据,因为这样造成的系统开销太大,作为替代,我们只使用一个指向该数据的地址(Android中使用的是
Uri,原理一样),这样操作起来也就更加有效率(相当于编程中的传值与传地址的区别)。
PS:大图裁剪同样用的是上述方法,都把生成的数据先保存到本地之后再通过
Uri来传递
运行结果
相关文章推荐
- Android静态变量的生命周期
- Android控件之ListView ChoickModel 单选、多选模式
- android JNI常用添加log方法
- android 关于paint的设置
- android 设计模式之Listview不同类型Item利用工厂模式的复用
- android屏幕适配终极指南(一):DPI,分辨率和屏幕尺寸
- Android初学习 - 调用startActivityForResult后,onActivityResult为什么立刻响应
- Android学习之简单理解布局的layout_gravity和gravity属性
- android 显示 PDF 文件
- Android ViewPager实现无限循环滑动
- 安卓开发如何提高Android程序的效率(转)
- 修改android包名
- 让Android项目健壮的几个建议
- android最佳性能实践
- Android常用代码之普通及系统权限静默安装APK
- listview原理
- Android 连续点击back button退出当前Activity的两种实现方法
- android 数据重构(仿淘宝浏览记录,足迹)
- android 数据重构(仿淘宝浏览记录,足迹)
- Android实现点击事件和长点击事件共存