Android Camera框架

1Android Camera 框架

Android <wbr>Camera框架

1.1 CameraFramework

Android <wbr>Camera框架

1.2 Camera TakePicture Image Display

Android <wbr>Camera框架

1.3 Camera Preview Display

Android <wbr>Camera框架

2 Camera应用层分析

com.android.camera这个包,几个主要的类文件如下: 

PhotoViewerGalleryPicker.java(所有图片集)--->ImageGallery.java(某个Folder下图片列表)--->ViewImage.java(看某张具体图片) 
VideoPlayer
GalleryPicker.java(所有视频集)--->MovieView.java(看某一个视频) 
Camera
Camera.javaCamera取景及拍照) 
VideoCamera
VideoCamera.javaVideoCamera取景及摄像)

Camera基本操作:

拍照预览:startPreview

停止预览:stopPreview

拍照:takePicture

 

Camera类中connect()是一个静态函数,它用于得到一个Camera的实例

回调函数:setShutterCallbacksetRawCallbacksetJpegCallback等,用于上层使用

android.hardware.Camera.ErrorCallback 摄像头出错时调用

android.hardware.Camera.open打开摄像头设备:

 mCameraDevice=android.hardware.Camera.open();

 

 

2.1一些回调接口控制Camera状态

2.1.1 android.hardware.Camera.ErrorCallback

android.hardware.Camera.ErrorCallback:摄像头出错的时候调用,这个接口具有一个void onError(int error,Cameracamera)函数;其中,

前者表示数据类型,取值是Camera类中的常量CAMERA_ERROR_UNKNOWN或者是CAMERA_ERROR_SERVICE_DIED

前者是不明错误,后者是表示服务已经关闭,

在这种情况下需要释放当前的Camera对象,然后再初始化一个。

privatestatic final class ErrorCallback implementsandroid.hardware.Camera.ErrorCallback { public void onError(interror, android.hardware.Camera camera) { if (error ==android.hardware.Camera.CAMERA_ERROR_SERVER_DIED) {mMediaServerDied = true; Log.v(TAG, "media server died"); } }}

2.1.2 android.hardware.camera.PreviewCallback

android.hardware.camera.PreviewCallback:在图像预览时调用,这个接口有一个void onPreviewFrame(byte[] data,Cameracamera);参数data为每帧图像的数据流。我们可以根据实际需要来实现这个接口。

2.1.3 android.hardware.Camera.ShutterCallback

android.hardware.Camera.ShutterCallback:在图像预览的时候调用,这个接口具有一个void onShutter();可以在改函数中通知用户快门已经关闭,例如播放一个声音。private final classShutterCallback implements android.hardware.Camera.ShutterCallback{ public void onShutter() { mShutterCallbackTime =System.currentTimeMillis(); mShutterLag = mShutterCallbackTime -mCaptureStartTime; Log.v(TAG, "mShutterLag = " + mShutterLag +"ms"); clearFocusState(); } }

4.android.hardware.Camera.PictureCallback:当拍摄相片的时候调用,该接口具有一个void onPictureTaken(byte[] data,Cameracamera)函数;参数和预览的一样。在android中主要有三个类实现了这个接口,分别是PostViewPictureCallbackRawPictureCallbackJepgPictureCallback。我们可以根据需要定义自己需要的类。

2.1.4 android.hardware.Camera.AutoFocusCallback

android.hardware.Camera.AutoFocusCallback:当自动对焦时候调用,该接口具有一个void onAutoFocus(boolean focused,Cameracamera)函数;

2.1.5 android.hardware.Camera.OnZoomChangeListener

还提供了放大缩小的监听器android.hardware.Camera.OnZoomChangeListener

3 解析图片

当取得照片的数据流后可以通过BitmapFactorydecodeByteArray()函数来解析图片。

另外还可以通过Camera对象的getParameters()函数来得到一个android.hardware.Camera.Parameters对象,Parameters提供了一些接口来设置Camera的属性:

1.setPictureFormat(int pixel_format):设置图片的格式,其取值为PixelFormat YCbCr_420_SPPixelFormatRGB_565或者PixelFormatJPEG

2.setPreviewFormat(int pixel_format):设置图片的预览格式,取值如上。

3.setPictureSize(int width,int height):设置图片的高度和宽度,单位为像素。

4.setPreviewSize(int width,int height):设置预览的高度和宽度,取值如上。

5.setPreviewFrameRate(int fps):设置图片预览的帧速。

在设置好Camera的参数后,可以通过函数void startPreview()开始预览图像、void stopPreview()结束预览,通过autoFocus(AutoFocusCallback cb)来自动对焦,最后可以通过takePicture(ShutterCallback shutter,PictureCallback raw, PictureCallback jpeg)函数来拍照。

该函数有三个参数,分别为快门回调接口、原生图像数据接口和压缩格式图片数据接口。

如果数据格式不存在的话数据流为空,如果不需要 实现这些接口则这些参数取值可以为null

4 拍照流程

AndroidCamera程序开发过程中,要用到Exif相关的知识,如果处理不当,会导致拍摄的JPEG图片无法正常浏览。在Froyo(Android 2.2)源码中的Camera应用是不对Exif信息进行写操作,而只是读操作,对于Exif的写操作是交给Camera硬件抽象层去完成,这是google的设计逻辑。但是不同的Android平台及其相关子平台,再加上不同的Camera应用,相互交替,排列组合,或许会出现这样一种情况:底层没有去写Exif,而上层应用也没有写Exif信息,那么图片的显示信息将会丢失。其中影响最为严重的是Orientation这个参数。

Froyocamera的逻辑是这样的:
Camera这个Activity中,有一个内部类ImageCapture,其中包含一个重要的方法:
private void capture() {
// Set rotation.
mParameters.setRotation(mLastOrientation);
....................
 mCameraDevice.setParameters(mParameters);

mCameraDevice.takePicture(mShutterCallback,mRawPictureCallback,mPostViewPictureCallback, new JpegPictureCallback(loc));
}

大致流程是这样的:

1)      获取设备 android.hardware.Camera.open(int)

2)      获取现有设置参数 getParameters()

3)      设置参数SetParameters(Camera.Parameters)

4)      设置预览预览顺时针角度 Camera.setDisplayOrientation(intdegrees)

5)      setPreviewDisplay(surfaceHolder) 设置这个才能预览,预览才能拍摄

6)      调用startPreview 执行预览

7)     拍照 takePicture(Camera.ShutterCallback,Camera.PictureCallback, Camera.PictureCallback,Camera.PictureCallback),并回到4个中的回调函数callback

8)      拍摄一张相片后,停止预览,如果想继续拍照,再次调用startPreview()

9)      调用stopPreview()停止预览

10)   调用release()释放设备

快速切换摄像模式:

1)      获取并初始化设备并且开始预览

2)      调用unlock()允许media进程访问Camera

3)      通过setCamera(Camera)切换模式,可以在MediaRecorder中看到拍摄视频设置

4)      当拍摄结束,调用reconnect重新后去并锁住Camera

5)      如果继续拍摄,可以重新调用startPreview()

6)      调用stopPreview()release() 退出Camera


 

1.将拍照时相机的方向添加进Camera.Parameters的实例中;
2.
将全部相机拍照参数传给android.hardware.Camera的对象;
3.
调用方法takePicture,并设置好非常重要的4callback;
4.
生成Exif数据的事情就由HAL来完成;
5.
4callback返回数据(这个callback是最重要的,而且是不可缺省的,也就是说前3callback设置成Null也不会影响拍照功能),见如下代码:
private final class JpegPictureCallback implements PictureCallback{
public void onPictureTaken(final byte[] jpegData, finalandroid.hardware.Camera camera) {
//jpegData
JPEG数据,是由HAL层根据应用传输的各种参数(Camera.Parameters的实例)以及JPEG压缩算法生成的。
mImageCapture.storeImage(jpegData, camera, mLocation);
}
}


 

Preview模式下,通过ClickShutterButtonCameraPreviw模式进入TakePicture模式。在进入TakePicture模式之前,需要关闭Camera的预览功能,即停止Camera Preview Display。在TakePicture模式下,AP层首先会发送一个Focus请求,Focus请求会直接到达CameraHardware层,CameraHardware调用底层硬件提供的接口完成Focus功能。并通过回调函数notify,发送CAMERA_MSG_FOCUS消息,完成Focus,在完成Focus之前,系统并不会停止Preview Display,只有上层接到底层返回的FOCUS成功消息之后,才真正的进入TakePicture模式。在进入TakePicture之后,Camera主要完成三个功能。

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值