android camera 学习

总体介绍

Android Camera框架从整体上看是一个client/service架构。有两个进程,一个是client进程,可以看成AP端

,主要包括Java代码和一些native层的c/c++代码;另一个是service进程,属于服务端,是native c/c++代码,

主要负责和linux kernel中的camera driver交互,搜集linux kernel中driver层传上来的数据,并交给显示系统(surface)显示。client 和 service 进程通过Binder机制进行通信,client端通过调用service端的接口实现各个具体的功能。

对于preview数据不会通过Binder机制从service端copy 到client端,但会通过回调函数与消息机制将preview数据的buffer地址传到client端,最终可在Java ap中操作处理preview数据。

2.调用层次划分

Android中Camera的调用流程可分为以下几个层次:

Package->Framework->JNI->Camera(cpp)--(binder)-->CameraService->Camera HAL->Camera Driver

client端:

Package 中的 camera.java 调用Framework中的 camera.java(framework/base/core/java/android/hardware).Framework中的 camera.java 调用 JNI层的native 函数。JNI层的调用实现在android_hardware_camera.cpp(framework/base/core/jni文件下的文件都被
编译进libandroid_runtime.so)文件中,android_hardware_camera.cpp文件中的 register_android_hardware_camera(JNIEnv *env)函数会将native函数注册到虚拟机中,以供framework层的JAVA代码调用,这些native函数通过调用 libcamera_client.so中的camera类实现具体功能。

核心的libcamera_client.so动态库源代码位于:framework/base/libs/camera中,其中 Icamera,IcameraClient,IcameraService三个类按照Binder IPC通信要求的框架实现的,用来与service端通信。

service端:

service端的实现在动态库libcameraservice.so中,源代码位于:frameworks/base/services/camera。CameraService相关类通过调用Camera HAL层来实现具体的功能,从HAL层向下就不是Android的标准代码了,各个厂商有自己不 同的实现。但思路应该都是相同的:Camera遵循V4L2架构,利用ioctl发送VIDIOC_DQBUF命令得到有效的图像数据,接着回调HAL层
的data callback接口以通知CameraService,CameraService会通过binder通知Camera.cpp。

ps查看进程,类似 com.android.camera是为客户端Camera进程,/system/bin/mediaserver是为服务端守护进程,由系统启动时开启。

n1,
camera打开线程与预览线程n

2,参数设置n

3,自动对焦与触摸对焦n

4,位置管理n

5,旋转管理n

6,拍照nA,对焦nB,拍照nC,接受图片nD,保存图片

1.打开camera与预览线程

onCreate()里会先后开启CameraOpenThread和CameraPreviewThread。

打开camera还需要线程?CameraOpenThread名为打开camera,实为C/S connect连接服务端,binder进程间通信,开销较大。预览线程必须在打开线程完成以后执行,它贯穿始终直到进程消亡为止,整个预览过程相对复 杂,在抽象层和底层驱动实现.

2.设置参数

—预览拍照录像之前,用户需要设置很多参数,比如闪光,白平衡,场景,对比度等。—程序里这些参数保存在SharedPreferences共享优选项和Parameters两个地方,Preferences包含Parameters,打开程序读取优选项参数,关闭程序保存优选项参数,考虑到用户经常会调整参数,引入Parameters来保存从打开以后到关闭以前这个中间过程的参数变量,Parameters的键值由抽象层根据硬件sensor的能力决定。

3.自动对焦与触摸对焦

—外界事物由光线经凸透镜聚焦到sensor上成像,camera模组开启马达前后平移镜头取得最佳成像效果,这个过程称之为对焦。—5.1
自动对焦—1)camera模组会因感光强度变化而自动开启对焦,驱动控制。—2)
用户长按快门,软件控制自动对焦。—3) 用户按下快门拍照,拍摄前自动对焦。—程序里,Camera对象实现类ShutterButton的接口OnShutterButtonListener里的方法onShutterButtonFocus(booleanpressed)和onShutterButtonClick(),后者是拍照,下节讨论,先看onShutterButtonFocus(booleanpressed),这个pressed判断是否为一次有效的长按,如果是的话,执行autoFocus(),这个autoFocus()也是Camera对象实现类FocusManager的接口Listener里的方法,由binder交给cameraservice,最后在底层驱动实现自动对焦。—5.2
触摸对焦—自动对焦的对焦区域位于屏幕正中,用户也可触摸特定区域对焦。—Camera对象实现类View的接口OnTouchListener里的方法onTouch(),输入系统上报MotionEvent的xy坐标,保存在Parameters,执行autoFocus(),抽象层读取Paramters的触摸点坐标,实现区域对焦。

4.存储位置管理

—位置管理LocationManager用来记录拍摄图片的GPS位置信息(经维度),存入JPEG头部插入的Exif里。—用户在菜单“相机设置”里的"保存所在位置"选择打开(前提是GPS已开启),屏幕左上方会出现一个GPS图标,表示现在可以记录GPS信息了。—程序里,Camera对象实现了位置管理监听器LocationManager.Listener的接口showGpsOnScreenIndicator()和hideGpsOnScreenIndicator(),显示或者隐藏GPS图标。—程序第一次初始化时initializeFirstTime(),通过读取优选项Preference得到bool值recordLocation,判断是否需要记录GPS信息,如果需要,在拍照capture()里调用LocationManager的方法得到Locationloc,并将其存入Exif。

5.旋转管理

—假设一台手机,camera正常安装,竖直方向作为默认方向(orientation==
0)拍摄照片,即拍摄“肖像照”(portrait),得到的照片显示在屏幕上也是竖直方向。—如果把手机旋转90度水平过来拍摄“山水照”(landscape),对于camerasensor来说,没有旋转的概念,所以软件上要把图片旋转90度回来。————————软件上,需要借助方向监听器随时更新方向信息,并保存在Parameters里,抽象层实现拍照功能时从Parameters里读取方向。—具体的,camera对象内部类MyOrientationEventListener的方法onOrientationChanged()保存方向orientation的值,MyOrientationEventListener继承OrientationEventListener,OrientationEventListener的onSensorChanged()把从sensorManager拿到的xyz坐标转换成方向。—程序启动,注册sensor监听器并使能,sensorManager不断上报底层sensor数据,通过消息机制发送到camera对象,后者计算坐标数据得到方向orientation的值(实际外包给orientationListener完成),最后保存Parameters。

6.拍照

—拍照分四步,对焦,拍照,接收图片,保存图片。—mCameraDevice.takePicture(mShutterCallback,mRawPictureCallback,—               
mPostViewPictureCallback, newJpegPictureCallback(loc));—1)对焦—拍照前如果已经区域对焦,则取消自动对焦,反之,开启一次自动对焦。对焦完成后,底层发送对焦成功与否的消息给camera对象,FocusManager把状态mState保存起来,如果正在对焦未完成(mState==
STATE_FOCUSING)则不可拍照,直到对焦完毕。—2)拍照—onShutterButtonClick()->
doSnap() -> capture() -> takePicture(),具体实现在抽象层和底层驱动,实质就是拿一张预览的图像,抽象层读取拍照时的Parameters参数配置,包括用户选择的照片大小。—3)接收图片—通过回调,由底层发送图片给camera对象。—RawPictureCallback,得到原始图片,需要软件压缩Jpeg。(YUV转Jpeg)—JpegPictureCallback,直接得到Jpeg图片,需要硬件压缩Jpeg。—PostViewPictureCallback,拍完后预览图片。—4)保存图片—交由线程ImageSaver保存图片和生成thumbnails。—默认路径位于/mnt/sdcard/DCIM/Camera/

android camera 学习

时间: 2024-12-22 08:52:10

android camera 学习的相关文章

Android Camera fw学习(四)-recording流程分析

Android Camera fw学习(四)-recording流程分析 备注:备注:本文是Android5.1学习笔记.博文按照软件启动流程分析.  且行且惜,一步一个脚印,这次学习camera Video.虽然标题是recording流程分析,但这里很多和preview是相似的(包含更新,创建Stream,创建Request),这里主要分析MediaRecorder对象创建.video帧监听对象注册.帧可用事件以及一系列callback流程分析. 一.认识video(mediaRecorde

Android学习十---Android Camera

Android camera用来拍照和拍摄视频的先看一下最后实现的效果图             最后的效果图 一.准备 在你的应用程序上使用android拍照设备,需要考虑以下几个方面 1. 是否是一定需要camera 如果需要,那么就无法安装在没有摄像头的设备. 需要在mainfest 中声明 <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:nam

Android硬件学习-照相机

学习Android不能不学习照相机,现在各种美容相机,微信朋友圈发图,现在升级之后直接下拉就可以照相了,各种艳照的的源头也是照相机,扯远了,有点邪恶了,还是简单学习一下Android中照相机的使用,Android中照相机的使用一般分为两种使用已有的照相App(可以理解为系统内置的照相机)和单独创建一个照相App,第一种方式简单易懂,第二种方式如果做的好的话可以养活一个公司~今天就简单的描述一下第一种的调用~ 基础工作 调用照相机需要照相,照相就需要存储,存在外部存储中需要设置权限,本次设置的三个

我的Android 4 学习系列之创建应用程序和Activity:Manifest、Application、Activity

目录 介绍Android应用程序组件,以及使用这些组件构建的各种Android应用程序 Android应用程序的生命周期 如何创建应用程序Manifest 如何使用外部资源提供对位置.语言和硬件配置的支持 如何实现和使用自己的Application类 如何创建新的Activity 理解Activity的状态转换和生命周期 Android应用程序的组成部分 Android应用程序是由松散耦合的组件构成的,并使用应用程序Manifest绑定到一起. Manifest描述了每一个组件以及他们之间的交互

Android Camera 通过V4L2与kernel driver的完整交互过程

http://blog.chinaunix.net/uid-26215986-id-3552456.html 原文地址:Android Camera 通过V4L2与kernel driver的完整交互过程 作者:xinyuwuxian 之前在 Android Camera 的执行流程 http://blog.chinaunix.net/uid-26765074-id-3499537.html 这篇文章中已经详细介绍了Android Camera app到调用open打开camera 设备的完成过

Android Camera 相机程序编写

Android Camera 相机程序编写 要自己写一个相机应用直接使用相机硬件,首先应用需要一个权限设置,在AndroidManifest.xml中加上使用设备相机的权限: <uses-permission android:name="android.permission.CAMERA" /> 为你的应用创建自定义的相机,一般步骤如下: 1.检测相机硬件并获取访问 2.建立一个Preview类:需要一个相机预览的类,继承 SurfaceView 类,并实现SurfaceH

java/android 设计模式学习笔记(14)---外观模式

这篇博客来介绍外观模式(Facade Pattern),外观模式也称为门面模式,它在开发过程中运用频率非常高,尤其是第三方 SDK 基本很大概率都会使用外观模式.通过一个外观类使得整个子系统只有一个统一的高层的接口,这样能够降低用户的使用成本,也对用户屏蔽了很多实现细节.当然,在我们的开发过程中,外观模式也是我们封装 API 的常用手段,例如网络模块.ImageLoader 模块等.其实我们在开发过程中可能已经使用过很多次外观模式,只是没有从理论层面去了解它. 转载请注明出处:http://bl

java/android 设计模式学习笔记(10)---建造者模式

这篇博客我们来介绍一下建造者模式(Builder Pattern),建造者模式又被称为生成器模式,是创造性模式之一,与工厂方法模式和抽象工厂模式不同,后两者的目的是为了实现多态性,而 Builder 模式的目的则是为了将对象的构建与展示分离.Builder 模式是一步一步创建一个复杂对象的创建型模式,它允许用户在不知道内部构建细节的情况下,可以更精细地控制对象的构造流程.一个复杂的对象有大量的组成部分,比如汽车它有车轮.方向盘.发动机.以及各种各样的小零件,要将这些部件装配成一辆汽车,这个装配过

java/android 设计模式学习笔记(一)---单例模式

前段时间公司一些同事在讨论单例模式(我是最渣的一个,都插不上嘴 T__T ),这个模式使用的频率很高,也可能是很多人最熟悉的设计模式,当然单例模式也算是最简单的设计模式之一吧,简单归简单,但是在实际使用的时候也会有一些坑. PS:对技术感兴趣的同鞋加群544645972一起交流 设计模式总目录 java/android 设计模式学习笔记目录 特点 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 单例模式的使用很广泛,比如:线程池(threadpool).缓存(cache).对