ANDROID Camera学习文档.docx
- 文档编号:23940015
- 上传时间:2023-05-22
- 格式:DOCX
- 页数:23
- 大小:716.29KB
ANDROID Camera学习文档.docx
《ANDROID Camera学习文档.docx》由会员分享,可在线阅读,更多相关《ANDROID Camera学习文档.docx(23页珍藏版)》请在冰豆网上搜索。
ANDROIDCamera学习文档
目录
1.0AndroidCamera系统框架3
1.1AndroidCamera概述3
1.2AndroidCamera模块各部分代码位置4
2.0Camera应用层详细分析5
2.1Camera应用主界面5
2.2Camera的预览功能整体调用流程7
2.3Camera的拍照功能整体调用流程8
2.4Camera的启动流程分析8
2.5Camera的相关功能详细分析9
2.5.1Camera的拍照录像切换功能9
2.5.2updateThumbnailButton()更新功能10
2.5.3shutterButton拍照按钮10
2.5.4布局文件11
2.5.5照相机SD卡11
2.5.6摄像机SD卡12
2.5.7取景预览的设置菜单项12
3.0Camera底层概要分析15
3.1AndroidCamera模块各部分之间的关系15
3.2client端程序部分15
3.3service端程序部分18
3.4CameraHAL(硬件抽象层)19
3.5底层调用机制分析19
1.0AndroidCamera系统框架
1.1AndroidCamera概述
Android的Camera包含取景器(viewfinder)和拍摄照片的功能。
目前Android发布版的Camera程序功能比较简单,其程序的架构分成客户端和服务器两个部分。
Camera在Android整体构架中的位置和关系可以用下图的表示:
图1.1Camera在Android整体构架中的位置和关系图
1.2AndroidCamera模块各部分代码位置
◆Camera的JAVA程序的路径:
packages/apps/Camera/src/com/android/camera/,在其中Camera.java是主要实现的文件
JAVA程序
libandroid_runtime.so
libui.so
libcameraservice.so
Camera硬件库
图1.2Camera的整体框架图
com.android.camera这个包下面,几个主要的类文件如下:
(1)Camera:
Camera.java(Camera取景及拍照)
(2)VideoCamera:
VideoCamera.java(VideoCamera取景及摄像)
●frameworks/base/core/java/android/hardware/Camera.java
这个类是中有些方法通过JNI的方式调用本地代码得到,有些方法自己实现。
●Camera的JAVA本地调用部分(JNI):
frameworks/base/core/jni/android_hardware_Camera.cpp,这部分内容编译成为目标是libandroid_runtime.so。
●Camera底层库在以下的目录中:
frameworks/base/libs/ui/,这部分的内容被编译成库libui.so。
●Camera服务部分:
frameworks/base/services/camera/libcameraservice/,这部分内容被编译成库libcameraservice.so。
●Camera主要的头文件:
frameworks/base/include/camera有以下几个:
(1)ICameraClient.h
(2)Camera.h
(3)ICamera.h
(4)ICameraService.h
(5)CameraHardwareInterface.h
在这些头文件Camera.h提供了对上层的接口,而其他的几个头文件都是提供一些接口类(即包含了纯虚函数的类),这些接口类必须被实现类继承才能够使用。
2.0Camera应用层详细分析
2.1Camera应用主界面
图2.1Camera拍照界面
图2.2Camera摄像界面
图2.3Camera菜单项
2.2Camera的预览功能整体调用流程
Camera:
应用层,实现界面布局和功能
CameraService:
Camera服务部分,连接应用层和底层
CameraHardwareInterface:
底层,用于完成Camera的功能
从上图可以看到预览功能在各层之间的调用流程,先用StartPreview开始准备预览,然后使用GetParameters得到参数,使用SetParameters设置参数;最后退出预览界面要调用StopPreview和ClosingCamera
2.3Camera的拍照功能整体调用流程
从上图可以看到拍照功能在各层之间的调用流程,先用Requestingautofocus获取焦点,使用GotShutterEvent,LatchedOrientation获取拍照时间,方向,然后使用GetParameters得到参数
拍照时使用TakePicture函数,底层将得到的jpeg图像通过回调函数返回上层,保存,完成拍照功能
2.4Camera的启动流程分析
一个activity启动调用流程:
onCreate()-->onStart()-->onResume()
(1)onCreate()
1.可添加所需布局文件,画界面。
2.开启线程,启动硬件摄像头,调用CameraHolder.instance().open()得到一个android.hardwareCamera实例mCameraDevice。
通过
ensureCameraDevice()-->CameraHolder.instance().open()-->mCameraDevice.getParameters()调用确保摄像头存在,并将摄像头打开。
然后使用startPreview(),开始取景预览
3.创建surfaceHolder,同时注册callback函数,当长宽变化时,调用SurfaceChanged()函数
mSurfaceView=(SurfaceView)findViewById(R.id.camera_preview);
SurfaceHolderholder=mSurfaceView.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
4.mIsImageCaptureIntent这个变量表示是否为从短信息或联系人编辑界面发送的intent到camera
mIsImageCaptureIntent=isImageCaptureIntent();当该函数返回true时,表示从短信息或联系人界面跳转到拍照界面;为false时,表示从桌面程序正常启动camera;要注意两种不同情况所需的右侧界面功能按钮区有变动。
(2)onStart()
mSwitcher.setSwitch(SWITCH_CAMERA)设置拍照录像切换按钮切换到照相模式。
(3)onResume()
主要调用startPreview()重新开始预览
1.当按home键退出程序时,会掉用stopPreview(),故再次进入时,会执行onResume()函数,在此函数中,使用mInitialThread重新开启预览功能。
然后开启一个新的进程计算图片大小等,
2.keepScreenOnAwhile()点亮屏幕,防止屏幕变黑。
2.5Camera的相关功能详细分析
2.5.1Camera的拍照录像切换功能
此功能涉及Switcher.java和camera.java两个文件
1.Switcher继承自ImageView,在布局文件中直接布局即可
2.mSwitch为true时,滑块在下方,显示拍照界面;当mSwitch为false时,滑块在上方,显示录像界面。
3.当点击或触碰拍照录像切换按钮时:
Switcher.java中调用流程如下
MotionEvent.ACTION_UP-->tryToSetSwitch()-->mListener.onSwitchChanged(this,onOff)
在camera.java中实现该接口,调用switchToVideoMode()-->MenuHelper.gotoVideoMode(this)-->startCameraActivity(),并结束当前程序
2.5.2updateThumbnailButton()更新功能
1.调用事件:
initializeFirstTime初始化时调用
initializeSecondTime()暂停或者重启时调用
Intent.ACTION_MEDIA_SCANNER_FINISHED,扫描SD卡结束时调用
2.mThumbController.isUriValid(),当图库里有图片时,值为TRUE;当图库里无图片时,值为FALSE。
3.updateLastImage()更新到相簿按钮上的显示图片。
4.mThumbController.updateDisplayIfNeeded()-->if(mUri==null)mButton.setImageDrawable(null);当图库无照片时,此处不显示任何照片
2.5.3shutterButton拍照按钮
1.对焦调用流程
按下屏幕上的ShutterButton按钮。
ShutterButton.java中的监听线程调用callShutterButtonFocus(),这个函数会调用接口ShutterButton.OnShutterButtonListener的函数onShutterButtonFocus()。
Camera.java实现了接口ShutterButton.OnShutterButtonListener。
故Camera.java中的函数onShutterButtonFocus()被调用。
接着的执行流程为----->doFocus()------>autoFocus()--->mCameraDevice.autoFocus()
2.拍照调用流程
之后ShutterButton.java调用performClick(),这个函数中调用了Camera.java中的onShutterButtonClick()
接着的执行流程为----->dosnap()----->ImagePicture.onSnap()----->ImageCapture.initiate()---->ImageCapture.capture()此函数执行完后,takepicture过程完成.
takePicture完成后,surfaceChanged()将被调用将刚照下的照片显示在屏幕上。
Camera.java中的回调接口JpegPictureCallback中的函数onPictureTaken()接着执行。
这个函数先调用ImageCapture.storeImage()将jpeg图像数据存储在内存。
3.picture的thumbnail显示过程:
ImageCapture.storeImage()--->ImageCapture.setLastPictureThumb()--->mThumbController.setData(uri,lastPictureThumb);
2.5.4布局文件
1.attach_camera_control.xml,当从短信息或联系人界面,进入camera时,功能按钮区的“确定”,“重拍”及“取消”
2.camera_control.xml,camera和videocamera主界面的功能按钮区的布局
3.camera.xml,camera主界面预览取景区的布局
4.video_camera.xml,videocamera主界面预览取景区的布局
5.on_screen_hint.xml,SD卡相关信息的输出,如在屏幕下方提示“使用相机前请先插入SD卡。
”
2.5.5照相机SD卡
1.BroadcastReceivermReceiver,接收SD卡发出的状态变化消息。
2.Intent.ACTION_MEDIA_MOUNTED挂载
Intent.ACTION_MEDIA_UNMOUNTED未挂载
Intent.ACTION_MEDIA_CHECKINGSD卡从未插入到插入的过程中会调用此状态
Intent.ACTION_MEDIA_SCANNER_FINISHED扫描SD卡结束,即SD卡进入可使用状态
3.checkStorage()->calculatePicturesRemaining()->MenuHelper.calculatePicturesRemaining()计算SD卡剩余空间
4.updateStorageHint()更新界面提示显示文字
其中MenuHelper.NO_STORAGE_ERROR包含SD卡状态:
MEDIA_CHECKING,MEDIA_SHARED,等SD卡状态
state=Environment.getExternalStorageState()获取SD卡状态
如state.equals(Environment.MEDIA_CHECKING)表示SD卡正在准备中
mStorageHint=OnScreenHint.makeText(this,noStorageText);设置当前界面需显示的内容
mStorageHint.show();显示SD卡状态文字
2.5.6摄像机SD卡
1.onResume()函数中注册receive事件
IntentFilterintentFilter=newIntentFilter(Intent.ACTION_MEDIA_MOUNTED);
intentFilter.addAction(Intent.ACTION_MEDIA_EJECT);
intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
intentFilter.addDataScheme("file");
mReceiver=newMyBroadcastReceiver();
registerReceiver(mReceiver,intentFilter);
mStorageStatus=getStorageStatus(true);
2.classMyBroadcastReceiver处理接收到的如上注册事件
比如其中
if(action.equals(Intent.ACTION_MEDIA_EJECT)){
updateAndShowStorageHint(false);
stopVideoRecording();
}当拔出SD卡时触发
3.updateAndShowStorageHint()->getStorageStatus()
此处当remaining==NO_STORAGE_ERROR,可添加如SHARE,CHECKING等状态的处理
根据不同的状态,返回不同的值
4.showStorageHint()
在switch(mStorageStatus)处理所需显示信息
例如,添加如下case语句,处理如上添加的SHARE状态
caseSTORAGE_STATUS_SHARE:
errorMessage=getString(R.string.sdcard_busy_message);
break;
5.mStorageHint=OnScreenHint.makeText(this,errorMessage);设置所需显示文字内容
6.mStorageHint.show();显示在当前摄像机界面中
2.5.7取景预览的设置菜单项
1、资源文件分析
相关的资源文件为Camera_preferences.xml和Video_preferences.xml,这两个文件中列举了Camera和VideoCamera两种模式下的不同菜单信息。
以Camera_preferences.xml为例,其中关于picture大小的菜单项信息为:
key="pref_camera_picturesize_key" camera: title="@string/pref_camera_picturesize_title" camera: entries="@array/pref_camera_picturesize_entries" camera: entryValues="@array/pref_camera_picturesize_entryvalues"/> 最终的菜单中只会显示这些配置文件当中底层硬件所支持的,如果硬件支持的大小与其中任何一种都不匹配,则不会显示出“Picturesize”菜单。 2、菜单的创建 在Camera.java文件中定义了类MainHandler,它里面有一个成员函数handleMessage(),它用来处理Camera应用程序中的message。 (1)case为FIRST_TIME_INIT时: 通过initializeFirstTime()---> changeHeadUpDisplayState()--->initializeHeadUpDisplay() 在initializeHeadUpDisplay()函数中,使用mHeadUpDisplay.initialize(this,settings.getPreferenceGroup(R.xml.camera_preferences))方法对camera_preference.xml资源文件进行处理 (2)然后对getPreferenceGroup进行分析: 通过getPreferenceGroup中initPreference()的ListPreferencepictureSize=group.findPreference(KEY_PICTURE_SIZE);将picture的大小信息存储在了结构体ListPreferencepictureSize中。 (3)语句 if(pictureSize! =null){ filterUnsupportedOptions(group,pictureSize,sizeListToStringList( mParameters.getSupportedPictureSizes())); } mParameters.getSupportedPictureSizes()获取了硬件Camera所支持的picture大小信息,在CameraHAL层的实现中,在函数initDefaultParameters()中设置了硬件所支持的picture大小。 CODE如下: CameraParametersp; p.set(“picture-size-values”,“1600x1200,1024x768,640x480”); 函数filterUnsupportedOptions()会将Camera应用和硬件支持的picture大小中两者匹配的大小存储在group中。 (4)函数mHeadUpDisplay.initialize()定义在文件 Packages/apps/camera/src/com/android/camera/ui/HeadUpDisplay.java中,通过initializeFirstTime()--->initializeHeadUpDisplay()--->initialize---> initializeIndicatorBar()--->addComponent(),将group中的picture大小添加到了菜单中。 3、菜单的监听事件 位于Camera.java中的MyHeadUpDisplayListener,通过onSharedPreferenceChanged()--->setCameraParametersWhenIdle()---> setCameraParameters()--->updateCameraParametersPreference() --->initialCameraPictureSize()--->setCameraPictureSize()的一系列调用,设置菜单选项 3.0Camera底层概要分析 3.1AndroidCamera模块各部分之间的关系 整个Camera在运行的时候,可以大致上分成Client和Server两个部分,它们分别在两个进程中运行,它们之间使用Binder机制实现进程间通讯。 这样在客户端调用接口,功能则在服务器中实现,但是在客户端中调用就好像直接调用服务器中的功能,进程间通讯的部分对上层程序不可见。 为了实现一个具体功能的Camera,在最底层还需要一个硬件相关的Camera库(例如通过调用videoforlinux驱动程序和Jpeg编码程序实现)。 这个库将被Camera的服务库libcameraservice.so调用。 在camera系统的各个库中,libui.so位于核心的位置,它对上层提供的接口主要是Camera类,类libandroid_runtime.so通过调用Camera类提供对JAVA的接口,并且实现了android.hardware.camera类。 libcameraservice.so是Camera的服务器程序,它通过继承libui.so的类实现服务器的功能,并且与libui.so中的另外一部分内容则通过进程间通讯(即Binder机制)的方式进行通讯。 libandroid_runtime.so和libui.so两个库是公用的,其中除了Camera还有其他方面的功能 ICameraService.h、ICameraClient.h和ICamera.h三个类定义了camera的接口和架构,ICameraService.cpp和Camera.cpp两个文件用于Camera架构的实现,Camera的具体功能在下层调用硬件相关的接口来实现。 从camera的整体结构上,类Camera是整个系统核心,ICamera类提供了Camera主要功能的接口,在客户端方面调用,CameraService是Camera服务,它通过调用实际的Came
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ANDROID Camera学习文档 Camera 学习 文档