android之系统相机拍照
在android系统上,调用相机是很简单也很有意思的事情。有两种方法,一种是直接调用摄像头,捕获图像然后自己处理;一种是调用系统或者第三方相机,然后使用返回的数据。这里说的就是第二种。
本文需要内存卡写权限和相机权限。
android 确实很伟大,调用相机很简单。
核心代码如下:启动activity,并在onactivity回调中 获取这个图片,很容易吧。下面的代码是把图片显示在一个imageView上。
// 启动系统相机 Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (intent.resolveActivity(getPackageManager()) != null) { startActivityForResult(intent, 100); } protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == 100 && resultCode == RESULT_OK) { Bitmap thumbnail = data.getParcelableExtra("data"); im.setImageBitmap(thumbnail); // Do other work with full size photo saved in mLocationForPhotos } } |
上述代码看起来不错,但是图片怎么这么小呢?查阅文档发现,此时data返回的是缩略图。且这个图片并没有存储,也就是说,关闭程序,就再也找不到这张图片,当然我们可以自己把这个缩略图存储起来。但问题是,我们拍照的原图去哪里了,或者该怎么获取?
查阅android官方文档,可以在启动相机的时候,设置存储路径,这样就可以获得原图了。代码如下:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //其中tempFile 在oncreate中,如下: // tempFile = new File(Environment.getExternalStorageDirectory(), // System.currentTimeMillis()+".jpg"); intent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(tempFile)); if (intent.resolveActivity(getPackageManager()) != null) { startActivityForResult(intent, 100); } protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == 100 && resultCode == RESULT_OK) { //设置照片存储路径后,有的机型返回的intent 就为null,这时不能从里面取数据了, // 需要从自己定义的路径取数据 // Bitmap thumbnail = data.getParcelableExtra("data"); Bitmap Opic = null; try { //读取文件。 Opic = BitmapFactory.decodeStream(new FileInputStream(tempFile)); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } im.setImageBitmap(Opic); // Do other work with full size photo saved in mLocationForPhotos } } |
以上代码主要是在启动相机的时候,传入了照片存储路径的额外参数,MediaStore.EXTRA_OUTPUT. 并在回调中从传入的路径中读取图片。从显示的结果来看,显示的是拍照的图片。
至此,好像一切万事大吉。拍照不过如此。但是细细研究发现,还有两点瑕疵:
1. 直接使用原图,如果图片很大,在一些手机上可能会内存溢出;
2. 我们存储的照片路径在系统媒体库中没有。
对于第一点,如果有很多图片,只是显示其缩略图,只有具体点击的时候才显示大图,或者本身我们不需要太大的图片,因而需要对图片做一些处理。
增加方法,缩放图片。代码如下:
/* * * 此方法并没有正在的改变原文件图片的大小。 * width、height 为参考的 宽和高,实际返回的大小由option.inSampleSize 确定 */ public Bitmap reSizePic(String path ,int width,int heith){ BitmapFactory.Options option = new BitmapFactory.Options(); //设置inJustDecodeBounds 为true之后,BitmapFactory.decodeFile 不返回bitmap,只是 //在option中返回图片的大小 option.inJustDecodeBounds = true; BitmapFactory.decodeFile(path,option); int oWidth = option.outWidth; int oHeihth = option.outHeight; System.out.println("-------------------- the originai size wihth and heigth "+oWidth+" , "+ oHeihth); System.out.println("-------------------- the request size wihth and heigth "+width+" , "+ heith); // 计算缩放量,这里只是简单的计算。 int scaleFactor = Math.min(oWidth/width, oHeihth/heith); //重新设置为false,返回图片 option.inJustDecodeBounds = false; //设置获得的图片的所放量,当为2时,返回的图片大小为原来的1/2 option.inSampleSize = scaleFactor; Bitmap res = BitmapFactory.decodeFile(path,option); System.out.println("-------------------- the resize real size wihth and heigth "+res.getWidth()+" , "+ res.getHeight()); return res; } |
注释已经写的很清楚了。另外onactivityResult回调稍微改一下,调用这个方法。
protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == 100 && resultCode == RESULT_OK) { //设置照片存储路径后,有的机型返回的intent 就为null,这时不能从里面取数据了, // 需要从自己定义的路径取数据 // Bitmap thumbnail = data.getParcelableExtra("data"); Bitmap Opic = null; // try { // //读取文件。 // Opic = BitmapFactory.decodeStream(new FileInputStream(tempFile)); // } catch (FileNotFoundException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } //缩放 Opic = reSizePic(tempFile.getAbsolutePath(), 480, 640); im.setImageBitmap(Opic); // Do other work with full size photo saved in mLocationForPhotos } } |
效果如下图,右边为打印的日志。
以上图片进行缩放后并没有存储,如果要进行存储,可以在适当时候调用以下方法。如果要覆盖原文件,只需要传入路径的时候传入原文件的路径就行。
/** * 把bitmap 保存未指定位置的文件,默认类型为JPG格式 */ public boolean saveBitMap(Bitmap bp,String desPath) { FileOutputStream out = null; boolean res = false; try { out = new FileOutputStream(desPath); bp.compress(CompressFormat.JPEG, 100, out); out.flush(); res = true; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { if (out != null) out.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return res; } |
至此图片缩放的工作完成。剩下更新多媒体库的问题。当我们采用类似以下代码来选择一张图片并返回的时候,我们发现,可选择的图片中,并没有我们之前调用相机拍照的图片(当然在文件管理的相应目录下可以看到)。
/** * 添加图片. */ public void addPhoto(int requetCode) { // 选择图片 requestCode 返回的标 Intent innerIntent = new Intent(Intent.ACTION_GET_CONTENT); innerIntent.addCategory(Intent.CATEGORY_OPENABLE); innerIntent.setType("image/*"); // 查看类型 Intent wrapperIntent = Intent.createChooser(innerIntent, "Add Photo"); startActivityForResult(wrapperIntent, requetCode); } |
为什么看不到我们刚才拍照的图片呢?这是android机制决定的。Android的媒体库信息实际上是以contentProvider提供的,媒体库在系统启动的时候扫描整个系统,把获得的媒体系统存储在内部db中,我们访问的实际上是db。所以当系统启动后,新增一张图片,在媒体库中是不可见。Android当然有更新媒体库的办法。方法调用如下,我们可以在拍完照返回的时候调用以下方法:
private void galleryAddPic(String path1) { Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); Uri contentUri = Uri.fromFile(new File(path1)); mediaScanIntent.setData(contentUri); this.sendBroadcast(mediaScanIntent); } |
上面的方法调用结果就不再贴图。至此问题基本解决完毕。
android之系统相机拍照相关推荐
- Android调用系统相机拍照并保存到指定位置
Android调用系统相机拍照并保存到指定位置 @Click(R.id.btn_takePhoto)void onclick() {Intent intent = new Intent(MediaSt ...
- android固定位置拍照,Android调用系统相机拍照并保存到指定位置
Android调用系统相机拍照并保存到指定位置 @Click(R.id.btn_takePhoto) void onclick() { Intent intent = new Intent(Media ...
- android 调用系统相机拍照 获取原图
博客源址:android 调用系统相机拍照 获取原图 博客时间:2013-04-23 11:08 好吧,为了这个问题又折腾了一整天.之前在网上找来的方法,如果在onActivityResult中直接用 ...
- Android调用系统相机拍照
参考: Taking Photos Simply FileProvider 项目地址(好多人找我要,我传到百度云啦,大家自取):链接:https://pan.baidu.com/s/1nWsoE0eS ...
- android异常相机处理,android 调用系统相机拍照的各种异常处理
1 本文只讨论调用系统相机出现的异常解决办法下面是调用系统相机的代码 先看一下最简单的写法 Intent intent = new Intent(android.provider.MediaStore ...
- Android 调用系统相机拍照和录制视频,保存照片和视频
1.申请权限 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> ...
- android相机保存文件为空,android 调用系统相机拍照,返回的data为null
最近做项目,需要拍照功能,于是就想简单的调用系统相机来完成这一需求(当然,如果想要个性化一点的,也可以自定义camera去实现,这里暂时不做). if(Environment.getExternalS ...
- Android 调用系统相机拍照,生命周期重走OnCreate,导致无数据的解决办法
extends:http://blog.csdn.net/b275518834/article/details/42347903 BUG具体体现为 : (1) 摄像头拍照后图片数据不一定能返回 ; o ...
- android 调用系统相机拍照并返回路径,Android调用相机拍照并返回路径和…
调用系统图库: Intent intent = new Intent(Intent.ACTION_PICK,MediaStore.Images.Media.EXTERNAL_CONTENT_URI); ...
最新文章
- 无线网络嗅探中的Radiotap
- 【控制】《多智能体系统的动力学分析与设计》徐光辉老师-第10章-带有分层领航者的多智能体系统的混杂协调
- C++字符串详解(二)访问与拼接
- JsonException: Max allowed object depth reached while trying to export from type System.Single
- 黑客(续) (压位高精+状压dp)
- android 关于关于子线程更新UI的一些事
- laravel的安装
- Android 应用开发(18)---在运行时请求权限
- bzoj 1600: [Usaco2008 Oct]建造栅栏(DP)
- 基于SSM的旅游信息平台
- LINUX下载编译libgsm
- (C语言)用C语言编写小游戏——扫雷
- lm算法c语言,lm算法(lm算法原理介绍)
- 拼图复原_玩过上百款拼图后,我总结出这份超详细的拼图年龄对照表!(收藏贴)...
- Oracle 官方文档在线查看Oracle函数
- win10下移动pagefiles.sys文件到D盘
- oracle数据库书籍mobi,Oracle Database 12c PL/SQL开发指南(第7版) pdf epub mobi txt 下载...
- pid纠偏算法C语言,基于MATLAB环境下智能PID纠偏控制算法的仿真分析.pdf
- 计算机链接投影蓝屏,怎么回事电脑与投影连接正常?电脑与投影连 – 手机爱问...
- 2018上海科技大学991数据结构与算法
热门文章
- LibLinear使用及与Lib的区别
- android自定义app图标下载,安卓换图标
- 日历记事本时钟java_java日历记事本(无敌版带提醒功能调整时区更换图片铃声功能)...
- cubase10学习笔记
- 文献精读(1)MRD,NSCLC
- Android之SeekBar(0在中间)
- Startup通过3D打印制造更便宜、更轻的火箭 | 广东省智能创新协会
- 准备好了吗?蒋宝藏带你详解判别分析!
- 装完某些软件之后IE主页被https://www.hao123.com/?tn=93453552_hao_pg劫持
- 统信UOS桌面操作系统专业版安装(版本号:V20.1043)