Android 拍照、从相册选择图片
来源:互联网 发布:wps重复数据筛选出来 编辑:程序博客网 时间:2024/06/05 04:44
在做Android图片上传功能的时候,获取图片的途径一般都有两种:拍照、从相册选择。
一、拍照
调用相机拍照有两种方法:
- 直接返回图片。
- 在调用相机的时候,传入uri,拍照后通过该uri来获取图片。
1.直接返回图片
private int TAKE_SMALL_PHOTO_REQUEST=0;//全局变量Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);startActivityForResult(intent, TAKE_PHOTO_REQUEST);
就是通过Intent发出隐式意图,制定action为MediaStore.ACTION_IMAGE_CAPTURE,来调用系统的相机。并返回相机拍的图片。在onActivityResult方法里接收。
@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_CANCELED) { Toast.makeText(context, "拍照取消!", Toast.LENGTH_LONG).show(); return; } if (resultCode == RESULT_OK) { switch (requestCode) { case TAKE_PHOTO_REQUEST: // 拍照返回结果 Bitmap photo = data.getParcelableExtra("data"); // 按需求处理photo break; } } }
返回的图片以bitmap的格式存放在data的key值是“date”中。取出后可进行相应的操作,比如显示、保存、上传。但是,要注意的是这是返回的bitmap是被系统用默认压缩方式压缩过的图片。那么要想获取原图或用自己的压缩方式处理怎么办呢?就要用到方法二了。
2.在调用相机的时候,传入uri,拍照后通过该uri来获取图片
//全局变量private int TAKE_BIG_PHOTO_REQUEST=1;private Uri imageUri;imageUri = createImageUri(context);//创建存储图片的uri,该方法见下边的讲解Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);startActivityForResult(intent, TAKE_BIG_PHOTO_REQUEST);@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_CANCELED) { deleteUri(imageUri, null, null);// 拍照取消,删除不用的文件 Toast.makeText(context, "拍照取消!", Toast.LENGTH_LONG).show(); return; } if (resultCode == RESULT_OK) { switch (requestCode) { case TAKE_BIG_PHOTO_REQUEST: // 直接使用之前新建的图片uri,来操作图片 // 按需求处理photo,比如显示 iv.setImageURI(imageUri); break; } } }
这种方法是向Intent中添加一条图片的uri数据,这时拍照完成后,系统会将图片存在这个uri中,在onActivityResult中,就可以直接使用这个uri操作图片了。隐式意图“MediaStore.ACTION_IMAGE_CAPTURE”和关键字“MediaStore.EXTRA_OUTPUT”也可以分别用“android.media.action.IMAGE_CAPTURE”和“output”代替。都是一个意思,只不过是不同的表示方法。
删除文件方法deleteUri(imageUri, null, null),参考我的一篇博客Android 根据Uri删除文件里的两种删除方法,文章的最后有一个综合方法,不同的方法为了兼容下边创建存储图片、获取uri的两种不同的方法。
创建存储图片、获取uri
1. 方法一
private Uri createImageUri(Context context){ Uri uri = null; if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){ String name = String.valueOf(System.currentTimeMillis()); ContentValues contentValues = new ContentValues(); contentValues.put(MediaStore.Images.Media.TITLE, name); contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, name + ".jpeg"); contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg"); uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues); } return uri;}
创建文件和获取uri同时进行。
首先将图片的文件信息保存在ContentValues 中,在通过ContentResolver类的insert方法来创建图片文件,并获取uri。该uri是以“content://”开头的,因此,可以用在Android 7.0以上版本。
优点:简单。
缺点:只能进行外部存储,存放图片的默认文件夹Pictures。原因是:
insert方法创建时只有两种存储方式:
1.EXTERNAL_CONTENT_URI,就是现在用的。
2.INTERNAL_CONTENT_URI,指向的是内部存储的根目录,而我们是访问不了的,会报错。
不熟悉外部存储和内部存储的小伙伴可以参考我的一篇博客Android内部存储与外部存储解析 希望对你有所帮助。
从原因的分析看,这种方法只能存在手机有外部存储的时候可以用,不过现在手机基本上都实现了SD内置本身就可以外部存储,不用担心这个。但是如果开发需求需要,存放在指定的文件夹怎么办,那看方法二了。
2.方法二
private Uri createImageUri(Context context,String myPath) { //创建文件 String state = Environment.getExternalStorageState(); File rootDir = state.equals(Environment.MEDIA_MOUNTED) ? Environment.getExternalStorageDirectory() : context.getCacheDir(); File folderDir = new File(rootDir.getAbsolutePath() + myPath);//myPath是图片存放的自定义的路径 if (!folderDir.exists() && folderDir.mkdirs()) { } String fileName = System.currentTimeMillis() + ".JPEG"; File tmpFile = new File(folderDir, fileName); // 调用parUri方法转成uri return parUri(tmpFile); } /** * 生成uri * @param cameraFile * @return */ private Uri parUri(File cameraFile) { Uri imageUri; String authority = context.getPackageName() + ".provider"; if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { //通过FileProvider创建一个content类型的Uri imageUri = FileProvider.getUriForFile(this, authority, cameraFile); } else { imageUri = Uri.fromFile(cameraFile); } return imageUri; }
这种方法是我要实现一个图片选择器的时候,看到LuckSiege开源框架里的一个方法,也引发了我对FileProvider类的学习,之后对FileProvider进行总结。
创建文件和获取uri分两步:
1. rootDir是外部存储的根目录,第二个参数可以自定义路径,比如“/photoTest/”;当不能进行外部存储的时候,调用getCacheDir()放在应用的cache目录下。
2. 转成Uri,Uri.fromFile(cameraFile)方法,传化成Uri以file://开头,这时如果想调用系统剪裁或与其他应用进行通信,在Android 7.0以上就会报错闪退。就要在SDK版本大于24时,用FileProvider.getUriForFile(this, authority, cameraFile)方法,转化成Uri以content://开头,来适用Android7.0以上。如上边的方法parUri(File cameraFile)。FileProvider使用时需要配置一些东西,网上有很多讲解,文章末尾有一个包含有配置demo可以下载。
这样就完美又灵活的实现了创建图片文件。
二、从相册获取
调用系统相册
Intent intent = new Intent();intent.setAction(Intent.ACTION_PICK); intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);startActivityForResult(intent, TAKE_ALBUM_REQUEST);@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); MLog.e("resultCode" + resultCode); if (resultCode == RESULT_CANCELED) { ToastUtil.showMessage(mContext, "取消设置图片!"); } if (resultCode == RESULT_OK) { switch (requestCode) { case TAKE_ALBUM_REQUEST: Uri uri = data.getData();// 获取选择图片的uri // 对uri进行处理 break; }}
调用系统图片很简单,不过一般系统图片会非常大,直接显示的时候,会报OOM。需要先进行压缩或剪裁的处理。在压缩或剪裁之前注意创建一个新的文件,处理后保存在新的文件里,否则就会处理后的图就会覆盖原图片,并且有些手机覆盖原图的时候会报错。
通过拍照、相册获取图片demo
- Android 从相册和拍照选择图片
- Android 拍照、从相册选择图片
- Android 实现从相册选择图片,拍照选择图片
- android 拍照+从手机相册选择返回图片到imagview
- Android图片裁剪(拍照和从相册选择)
- Android从相册选择图片和调用系统摄像头拍照
- 拍照和从相册选择图片 截图
- 拍照和从相册选择图片
- 拍照和从相册选择图片
- android 选择图片 相册选择 马上拍照
- Android 选择图片 相册选择 马上拍照
- Android 从相册选择照片 手机拍照
- Android 拍照/相册 选择图片工具
- android 拍照和选择相册图片剪切
- Android 从相册选择图片
- Android上传图片之调用系统拍照和从相册选择图片
- Android上传图片之调用系统拍照和从相册选择图片
- 拍照上传图片与从相册中选择图片上传
- React 入门实例教程
- 使用dpdk测试平台转发性能
- html符号
- Gym
- Noip2015 Day1 T3 斗地主(Dfs+Dp优化)
- Android 拍照、从相册选择图片
- Jquery对象和javascript对象相互转换
- python 通过国内镜像使用pip安装工具包
- 第二章 Git 基础
- Java 工具类
- 几天前,几秒前时间格式转换
- C++编程相关——综合
- jQuery 常规选择器
- Ambari--服务管理