Android官方开发文档Training系列课程中文版:调用相机之简单拍照

原文地址:http://android.xsoftlab.net/training/camera/index.html

导言

在富媒体开始流行之前,整个世界是一个灰暗且平淡无奇的地方。还记得Gopher吗?我或许不记得了。自从APP成为用户生活的一部分之后,这便给他们提供了一种方式可以来存放他们生活的细节。使用设备上的相机,程序可以使用户扩大周围的视野或者见解,使以独特的化身,记录各个角落里的奇闻异事,或者只是简单的分享他们的境遇。

这节课会通过已有的相机应用以超级简单的方式快速过一下。在稍后的课程中会逐渐深入的学习如何直接控制相机硬件。

简单拍照

这节课会展示如何使用已有的相机应用来拍照。

假设你正在实现一个众包的天气服务程序,这个服务可以使运行在设备上的客户端APP通过天空的混合照片生成全部的天气示意图(言下之意就是可以生成各种天气的天气图像),而整合照片只是程序很小的一部分功能。你并不想在这里花费很多时间,也不想彻底的改造相机程序。幸运的是,大多数的安卓设备至少已经安装了一款相机应用。这节课就是学习如何利用这个应用为程序拍一张照片。

请求相机权限

如果拍照是程序的一项必要需求,那么需要在Google Play上限制它的分类为拥有相机类。为了告知系统程序是基于相机的,需要在清单文件中添加 标签。

<manifest ... ><uses-feature android:name="android.hardware.camera"android:required="true" />...
</manifest>

如果程序需要使用,但是为了整个功能而不强制要求相机,那么可以设置android:required为false。这样做的话,Google Play会允许不带相机的设备下载你的程序。不过你有责任需要在运行时通过调用hasSystemFeature(PackageManager.FEATURE_CAMERA)方法检查设备上的相机是否可用。如果相机是不可用的,你应该禁用掉与相机相关的功能。

通过相机APP拍照

Android通过授权的方式让其他程序通过调用一个Intent来描述你想要做的事情。这个过程包含了三块:Intent本身,一个启动外部Activity的调用,以及一些当焦点返回Activity时处理图像数据的代码。

下面代码的功能用于调用一个意图来拍摄照片:

static final int REQUEST_IMAGE_CAPTURE = 1;
private void dispatchTakePictureIntent() {Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);if (takePictureIntent.resolveActivity(getPackageManager()) != null) {startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);}
}

要注意,startActivityForResult()方法被一个调用resolveActivity()方法的条件所保护,这个方法返回了可以处理这个Intent的第一个activity组件。执行这项检查是非常重要的,因为如果你调用startActivityForResult()方法所使用的Intent没有APP可以处理的话,那么你的APP将会崩溃。所以只要结果不是null,那么就意味着可以安全使用这个Intent。

获取缩略图像

如果简单的拍照功能并不是APP的主要功能,那么你可能想通过相机应用获得一张照片,并且利用这张照片做点什么事情。

Android的相机应用会将照片作为一个小的Bitmap对象打包进Intent中,然后通过onActivityResult()方法将该Intent返回。具体的Bitmap对象会附加在键”data”后。下面的代码段接收到这个图像,并将它展示到了一个ImageView中:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {Bundle extras = data.getExtras();Bitmap imageBitmap = (Bitmap) extras.get("data");mImageView.setImageBitmap(imageBitmap);}
}

Note: 从”data”中获得的缩略图像可能适合用于图标上面,但不适用于很大的图标。处理全尺寸的图像需要花费更多一点的工作。

保存全尺寸照片

如果你提供了文件的保存路径的话,那么Android相机应用会将全尺寸的照片保存在这个地方。你必须提供文件的全路径,这个路径所指向的地方就是相机应用将要保存照片的地方。

通常情况下,用户通过相机应用所拍摄的任何照片都应该被保存在设备外部存储器上的一个公共文件夹中,这样就可以使所有的APP都可以访问。这个适用于存放共享照片的目录由getExternalStoragePublicDirectory()提供,并需要传递DIRECTORY_PICTURES参数。因为由这个方法所提供的分享目录适用于所有的APP,读取以及写入分别需要READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE权限。写入权限隐式地包含了读取权限,所有如果你需要写入到外部存储上的话,只需要请求一个权限就可以:

<manifest ...><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />...
</manifest>

然而,如果你希望这些照片只是被保存在APP的私有目录中的话,你可以使用getExternalFilesDir()方法提供的目录来做替换方案。在Android 4.3之前,写入到这个目录需要WRITE_EXTERNAL_STORAGE权限。从Android 4.4开始,这个权限不再被需要,因为这个目录不再对其它APP可见,所以这里声明的权限只对低版本的Android适用,并需要添加maxSdkVersion属性:

<manifest ...><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"android:maxSdkVersion="18" />...
</manifest>

Note:当用户卸载了你的APP时,那么通过getExternalFilesDir()方法所提供的目录下的文件也会一并删除。

一旦你决定了文件存储的目录,需要创建一个防止冲突的文件名称。你可能还希望将路径保存到一个成员变量中,以便稍后再使用。这里在方法中有一个示例的解决办法,它会通过日期时间戳来对新照片返回一个唯一的文件名称:

String mCurrentPhotoPath;
private File createImageFile() throws IOException {// Create an image file nameString timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());String imageFileName = "JPEG_" + timeStamp + "_";File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);File image = File.createTempFile(imageFileName,  /* prefix */".jpg",         /* suffix */storageDir      /* directory */);// Save a file: path for use with ACTION_VIEW intentsmCurrentPhotoPath = "file:" + image.getAbsolutePath();return image;
}

随着这个方法可用来对照片创建文件,你现在可以创建并且调用Intent,就像这样:

static final int REQUEST_TAKE_PHOTO = 1;
private void dispatchTakePictureIntent() {Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);// Ensure that there's a camera activity to handle the intentif (takePictureIntent.resolveActivity(getPackageManager()) != null) {// Create the File where the photo should goFile photoFile = null;try {photoFile = createImageFile();} catch (IOException ex) {// Error occurred while creating the File...}// Continue only if the File was successfully createdif (photoFile != null) {takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(photoFile));startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);}}
}

添加照片到相册

当你通过一个意图创建了一张照片,你应该知道图像位于何处,因为在上面的代码中你告诉了照片保存的位置。对于其他人而言,可能使照片最简单的访问方式就是使照片对系统的媒体扫描器(Media Provider)是可访问的。

Note: 如果照片保存的文件目录是由getExternalFilesDir()所提供的,那么,媒体扫描器是不能访问这些文件的,因为照片对于你的APP来说是私有的。

下面的示例方法演示了如何调用系统的扫描器来添加你的照片到媒体扫描器(Media Provider)的数据库中,使得这些照片可以被系统的相册应用或者其它APP可访问:

private void galleryAddPic() {Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);File f = new File(mCurrentPhotoPath);Uri contentUri = Uri.fromFile(f);mediaScanIntent.setData(contentUri);this.sendBroadcast(mediaScanIntent);
}

解码缩放图像

在一定的内存中管理多个全尺寸的图像可能是很棘手的。如果你发现你的程序在展示了几张图片之后造成了内存溢出,那么可以通过将JPEG图像缩放到目标视图的尺寸大小的方式来显著的降低堆内存的使用量。
下面的示例方法演示了这一技术:

private void setPic() {// Get the dimensions of the Viewint targetW = mImageView.getWidth();int targetH = mImageView.getHeight();// Get the dimensions of the bitmapBitmapFactory.Options bmOptions = new BitmapFactory.Options();bmOptions.inJustDecodeBounds = true;BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);int photoW = bmOptions.outWidth;int photoH = bmOptions.outHeight;// Determine how much to scale down the imageint scaleFactor = Math.min(photoW/targetW, photoH/targetH);// Decode the image file into a Bitmap sized to fill the ViewbmOptions.inJustDecodeBounds = false;bmOptions.inSampleSize = scaleFactor;bmOptions.inPurgeable = true;Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);mImageView.setImageBitmap(bitmap);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/479181.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

谈谈工业界落地能力最强的机器学习算法

尽管BERT为代表的预训练模型大肆流行&#xff0c;但是身处工业界才会知道它落地有多难&#xff0c;尤其是QPS动辄几百的在线推荐、搜索系统&#xff0c;哪怕在大厂也很难在线上系统见到它们。 今天就想反其道而行之&#xff0c;谈谈工业界搜索、推荐、广告这类核心场景中落地能…

论文浅尝 | 中科院百度微软等学者最新综述论文40+最新方法阐述知识图谱提升推荐系统准确性与可解释性...

本文转载自公众号&#xff1a;先知。【导读】近来&#xff0c;知识图谱用于推荐系统是关注的焦点&#xff0c;能够提升推荐系统的准确性与可解释性。如何将知识图谱融入到推荐系统呢? 最近中科院计算所百度微软等学者最新综述论文《A Survey on Knowledge Graph-Based Recomm…

美团酒旅起源数据治理平台的建设与实践

背景 作为一家高度数字化和技术驱动的公司&#xff0c;美团非常重视数据价值的挖掘。在公司日常运行中&#xff0c;通过各种数据分析挖掘手段&#xff0c;为公司发展决策和业务开展提供数据支持。 经过多年的发展&#xff0c;美团酒旅内部形成了一套完整的解决方案&#xff0c;…

LeetCode 1103. 分糖果 II

1. 题目 排排坐&#xff0c;分糖果。 我们买了一些糖果 candies&#xff0c;打算把它们分给排好队的 n num_people 个小朋友。 给第一个小朋友 1 颗糖果&#xff0c;第二个小朋友 2 颗&#xff0c;依此类推&#xff0c;直到给最后一个小朋友 n 颗糖果。 然后&#xff0c;我…

计算广告与推荐系统有哪些区别?

文 | King James本文已获作者授权&#xff0c;禁止二次转载计算广告和推荐系统总感觉有千丝万缕的关系&#xff0c;但是它们之间又有什么异同呢&#xff1f;话不多说&#xff0c;上图&#xff01;计算广告和推荐系统有交集&#xff0c;但是不能说推荐系统是计算广告的一部分。因…

Android官方开发文档Training系列课程中文版:调用相机之简单摄像

原文地址&#xff1a;http://android.xsoftlab.net/training/camera/videobasics.html 这节课解释了如何通过已有的相机应用拍摄视频。 假设你的程序含有摄像功能&#xff0c;但是它只是程序很小的一部分功能&#xff0c;你并不想在这么小的功能上花费很大的精力。幸运的是&a…

解决cuda版本与pytorch版本不兼容问题

解决PyTorch与CUDA版本不匹配&#xff1a; 2 pytorch官网查看安装命令 https://pytorch.org/get-started/locally/ 如果你发现你的版本与上面的都不符合&#xff0c;可以点击 进入以前版本页面&#xff1a;https://pytorch.org/get-started/previous-versions/的安装命令&am…

论文浅尝 | 重新实验评估知识图谱补全方法

论文作者&#xff1a;Farahnaz Akrami&#xff0c;美国德州大学阿灵顿分校&#xff0c;博士生。笔记整理&#xff1a;南京大学&#xff0c;张清恒&#xff0c;硕士生。链接&#xff1a;https://arxiv.org/pdf/2003.08001.pdf代码&#xff1a;https://github.com/idirlab/kgcomp…

Android组件化方案及组件消息总线modular-event实战

背景 组件化作为Android客户端技术的一个重要分支&#xff0c;近年来一直是业界积极探索和实践的方向。美团内部各个Android开发团队也在尝试和实践不同的组件化方案&#xff0c;并且在组件化通信框架上也有很多高质量的产出。最近&#xff0c;我们团队对美团零售收银和美团轻收…

Android官方开发文档Training系列课程中文版:调用相机之控制相机

原文地址&#xff1a;http://android.xsoftlab.net/training/camera/cameradirect.html 在这节课&#xff0c;我们会讨论如何使用Android框架API来直接控制相机硬件。 直接控制设备的相机拍照或者摄像的代码远比通过其他相机应用来完成要多得多。然而&#xff0c;如果你想构建…

我,大学没毕业,在OpenAI搞AI,想教教你如何提升“研究品味”

文 | 蒋宝尚源 | AI科技评论在AI圈里有这么一个人&#xff0c;虽然大学没有毕业&#xff0c;但却做过谷歌大脑研究员&#xff0c;担任过OpenAI团队的领导人。他被人称作“怪胎”&#xff0c;也被人称作神童。他的名字叫做Chris Olah。在众人眼里&#xff0c;他的成长树在一开始…

LeetCode 889. 已知前序后序 求二叉树(不唯一)

1. 题目 返回与给定的前序和后序遍历匹配的任何二叉树。 pre 和 post 遍历中的值是不同的正整数。 示例&#xff1a;输入&#xff1a;pre [1,2,4,5,3,6,7], post [4,5,2,6,7,3,1] 输出&#xff1a;[1,2,3,4,5,6,7]来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链…

cuda run out of memory内存不足的解决方案

https://segmentfault.com/a/1190000022589080

论文浅尝 | TANDA: Transfer and Adapt Pre-Trained Transformer Models

论文笔记整理&#xff1a;王春培&#xff0c;天津大学硕士。链接&#xff1a;https://arxiv.org/pdf/1911.04118.pdf动机这篇文章聚焦的是问答系统&#xff08;Q&A&#xff09;中的一个问题&#xff1a;回答句子选择&#xff08;Answer Sentence Selection&#xff0c;AS2&…

深入浅出排序学习:写给程序员的算法系统开发实践

引言 我们正处在一个知识爆炸的时代&#xff0c;伴随着信息量的剧增和人工智能的蓬勃发展&#xff0c;互联网公司越发具有强烈的个性化、智能化信息展示的需求。而信息展示个性化的典型应用主要包括搜索列表、推荐列表、广告展示等等。 很多人不知道的是&#xff0c;看似简单的…

从ScrollView嵌套EditText的滑动事件冲突分析触摸事件的分发机制以及TextView的简要实现和冲突的解决办法

本篇文章假设读者没有任何的触摸事件基础知识&#xff0c;所以我们会从最基本的触摸事件分发处说起。 ScrollView为什么会出现嵌套EditText出现滑动事件冲突呢&#xff1f;相信你会有这种疑问&#xff0c;我们来看这么一种情况&#xff1a; 有一个固定高度的EditText&#xff…

LeetCode 1185. 一周中的第几天

1. 题目 给你一个日期&#xff0c;请你设计一个算法来判断它是对应一周中的哪一天。 输入为三个整数&#xff1a;day、month 和 year&#xff0c;分别表示日、月、年。 您返回的结果必须是这几个值中的一个 {“Sunday”, “Monday”, “Tuesday”, “Wednesday”, “Thursda…

使用NLP和ML来提取和构造Web数据

原文链接&#xff1a;https://blog.csdn.net/fendouaini/article/details/109374462 作者|Conner Brew 编译|VK 来源|Towards Data Science 介绍 在本文中&#xff0c;我们将创建一个基于战争研究所&#xff08;ISW&#xff09;的结构化文档数据库。ISW为外交和情报专业人员提供…

如何评价一个推荐系统的好坏?

文 | Nemo知乎本文已获作者授权&#xff0c;禁止二次转载现如今&#xff0c;推荐系统几乎无处不在。电商购物&#xff0c;有猜你喜欢。资讯阅读&#xff0c;有个性推荐。听歌看电影&#xff0c;都能识别你的兴趣。就连工作社交&#xff0c;也会提示你可能认识的人...推荐系统火…

论文浅尝 | GEOM-GCN: Geometric Graph Convolutional Networks

论文笔记整理&#xff1a;毕祯&#xff0c;浙江大学硕士&#xff0c;研究方向&#xff1a;知识图谱、自然语言处理。动机消息传递神经网络&#xff08;MPNN&#xff09;已成功应用于现实世界中的各种应用中。但是MPNN聚合器的两个基本弱点限制了它们表示图结构数据的能力&#…