InstaMaterial 概念设计(8) – 拍照功能

758 查看

今天,我们将实现照相功能,这个功能在演示在概念视频的38 到 41秒之间。因为相机的实现略为复杂,我们将忽略一些细节(比如FAB 按钮的动画,颜色,图标)。在下一章(也可能是最后一章)中回头再讲他们。

我必须提醒的是因为只是产权的原因,InstaMaterial已经从Google Play Store下架。这点我完全理解,在也许会准备一个布局和Instagram完全不一样的版本(但是概念视频中的所有效果都将保留)。

今天的代码所编译的apk文件可以在 这里 下载。

回到我们的文章内容- 下面是今天要实现的最终效果:

介绍

今天所描述的几乎所有动画和解决办法都在前面的文章中已经提到了,这也是为什么我不再把这些细节作为重点的原因。但是,有一个完全新的东西- 相机。接触过相机编程的同学应该知道这个组建实现起来是很让人为难的,为什么呢?简单的来说就是:安卓是一个开放的平台,需要适配许多硬件完全不同(尤其是相机)的设备。因此如果你和照相打交道,你需要关注以下事情:

  • 不同的预览和捕获到的图像尺寸每一个设备都只支持有限的尺寸(不管是预览还是拍照的图像)。记住,有些设备不能处理1:1的比率(squared image) – 实际上 Nexus 5 就是这样的设备之一。
  • 后置/前置摄像头
    每个设备都应该有前置和后置摄像头,当然有些只有后置摄像头,不过记住,有些设备只有前置摄像头(比如2012年的Nexus 7),这些设备的拍出来的像素大小都是不一样的。
  • 相机所支持的功能也不一样有些设备不支持自动对焦,还有一些不支持变焦,在使用这些功能之前先应该先检查它们是否存在。
  • 相机的操作开销很大始终记住维护图像(尤其是高分辨率的图像)是开销很大的一件事。图像处理不轻松,你需要关注内存的管理并且在UI主线程之外计算。另外相机被调用之后并不会立即可以使用,有时候你需要等待它做一些初始化工作。

考虑到以上描述的几点,我决定使用第三方的库来处理相机操作,而不是自己写代码实现。我选择了CWAC-Camera 库 ,虽然实现起来还是比较复杂,但是它处理好了很多比较偏的问题。即使作者计划完全重写它,但是在我看来,也很难找到更好的方法来处理图像和视频了。

最后提一点,InstaMaterial app中所实现的相机功能非常有限。没有图片文件的处理同时显示捕获照片也是用的比较取巧的方法。在用在产品级应用之前还需要做很多工作(尤其是图片裁剪,图片的合适尺寸等)。不过我相信这些代码作为更复杂项目的基本代码框架还是非常不错的。

准备

如往常一样,先添加资源做一些琐碎的准备工作吧。也有一些库的更新,下面是新的代码结构:

别把它看成是最终的参考,但是在实际项目中这种结构是我的最爱,UI,逻辑,数据被分开(另一种是根据功能分,但是在小项目中使用会觉得比较累赘)。

下面是提交到东西:

CWAC-Camera 配置

Camera库的安装很简单。只需在 <project>/build.gradle中添加新的maven repository:

在 <project>/app/build.gradle中添加新的依赖:

最后需要在 AndroidManifest.xml 文件中添加新的权限:

照相界面

现在可以开始实现捕获的屏幕了。我考虑了两种实现方式 – 用两个Activity分别用于照相和编辑 或者 两者都在一个Activity中完成。第一种选择也许更合理些(在我们的正式项目中也也许就是采用这种方案),但是我还是选择了第二种办法。为什么?因为没有一种简单的方法使从相机预览过渡到图片预览不会卡顿。默认情况相机将拍摄的照片保存在内存卡中,另外一个Activity需要从那里读取,不幸的是这会产生一点延迟,因此我们需要想办法让bitmap在两个Activity之间传递(这个过程要比通过Intent传递bitmap或者将bitmap作为静态变量保存要复杂得多)。

让我们从入场动画开始。Activity 过渡我们可以使用 上篇文章 中介绍的RevealBackgroundView。我们需要再一次将起始位置(FAB按钮的位置)传递过去,唯一不同的是这次我们需要添加新的样式来隐藏TakePhotoActivity中的状态栏:

在AndroidManifest中设置