相机显示知识:
- Camera
- SurfaceView (SurfaceView 也是TextureView,最常用的当然是SurfaceView 所以主讲SurfaceView)
俩者关系脑图
一、SurfaceView 、Surface 、 SurfaceHolder
关系图
Surface
Surface用来处理屏幕内容合成器所管理的原始缓存区的工具,由图像缓冲区的消费者(如:Surfacetexture)创建然后移交给生产者(如MeddiaPlayer) 或者是显示到(如:CameraDevice)
SurfaceHoler
抽象接口,给持有surface的对象使用,可以控制surface的大小和格式,编辑Surface种的像素,以及监听surface的变化,这个接口通过SurfaceView获得
SurfaceHoler中有一个Callback的接口通过脑图大家可以看到,它的回调方法有3个
- surfaceCreated(SurfaceHolder holder) suface第一次调用的时候回调
- surfaceChanged(SurfaceHolder holder,int format ,int width ,int height) surface变化的时候回调 变化为大小和格式
- surfaceDestroyed(SurfaceHolder holder) suface销毁的时候回调
SurfaceView
SurfaceView提供了嵌入视图层级种的专用Surface,我们可以控制Surface的格式和大小。
SurfaceView则负责把Surface现实在屏幕的正确位置
SurfaceView 其实也是继承自View,其中俩个成员变量,一个是Surface对象一个是SurfaceHolder对象。
- SurfaceView把Surface现实在屏幕
- SurfaceView通过SurfaceHoder告诉我们Surface的3个状态 (创建 变化 销毁)
- SurfaceView可以通过getHolder()方法获得当前SurfaceView的SurfaceHolder对象让就可以对SurfaceHolder对象添加回调的Surface进行监听状态
- SurfaceView是View的对象
- SurfaceView中有俩个对象,Surface和SurfaceHolder
- 通过getHolder()方法获得当前SurfaceView的SurfaceHolder对象
二 、 Camera
Camera类中的内部类
CameraInfo 用来描述相机信息,通过Camera中getCameInfo(int camerald,CameraInfo cameraInfo)方法获得,主要包括一下成员变量。
- facing facing代表相机的方向,它的值只能是CAMERA_FACING_BACK(后置摄像头)和CAMERA_FACING_FRONT(前置摄像头)。
CAMERA_FACING_BACK(后置摄像头)和CAMERA_FACING_FRONT(前置摄像头)Camera中的静态变量
- orientation orientaion是相机采集的角度,他的值是采集到的图片顺时针旋转自然的角度值,它必须的0,90,180,270中的一个。 因此可以就可以知道在拿到相机拍照的时候角度为60的话那么它在怎么旋转也不是可以为正的原因。
- setDisplayOrientation 设置预览图片的顺时针角度。注:这个方法会影响预览图像个拍照后现实的图片,这个方法对竖屏应用和图片非常有效。然后是前摄像头在进行角度旋转之前,图像会进行一个水平的镜像反转,所以你打开相机预览图像的时候如同照镜子,但是拍下照来才发现是水平方向的镜像。 注:setDisplayOrientation(int degrees)是Camea类中的一个方法,之所以穿插在这里来讲,是为了和上面提到的orientation做一个统一讲解,因为这两个都涉及到了方向问题
- 屏幕坐标 在Android系统中,屏幕的左上角是坐标系统的圆点(0,0)坐标。原点向右是X轴的正方向,原点向下是Y轴的正方向。
- 自然方向 每个设备都有一个自然方向,手机和平板的自然方向不同。手机的自然方向是 portait(竖屏),平板的就是(landscape) 横屏
- 图像传感器 (imager Sensor) 方向 手机相册的图像数据都是来自摄像头硬件的图像传感器,这个传感器被固定到手机后的一个默认的取景方向
- 相机的预览方向 将图像传感器捕获的图像,现实在屏幕上的方向。在默认 情况下,与预想传感器方向一致。在相机API中通过setDisplayOrientation()设置相机预览方向在默认情况下,这个值为0与图像传感器方向一致。
-
绝大部分安卓手机中图像传感器方向是横向的,且不能改变,所以orientation是90或是270,也就是说,当点击拍照后保存图片的时候,需要对图片做旋转处理,使其为"自然方向"。 (可能存在一些特殊的定制或是能外接摄像头的安卓机,他们的orientation会是0或者180)
-
通过setDisplayOrientation方法设置预览方向,使预览画面为"自然方向"。前置摄像头在进行角度旋转之前,图像会进行一个水平的镜像翻转,所以用户在看预览图像的时候就像照镜子一样。
Camera内部类
SiZi 图片大小包含俩个变量:width和height (图片的宽和高)
Parameters
Parameters是相机服务设置,不同的相机可能是不相同的。比如相机所支持的图片大小,对焦模式等等。下面介绍一下这个类中常用的方法
- getSupportedPreviewSizes() 获得相机支持的预览图片大小,返回值是 List(Sizi)
- setPreviewSize(int width, int height) 设置相机预览的图片大小
- getSupportedPreviewFormats() 获取相机支持的图片格式
- setPreviewFormat(int pixel_format) 设置图片的预览格式
- getSupportedPictureSizes() 获取相机支持的采集图片大小(就是拍照后保存的图片大小)
- setPictureSize(int width, int height) 设置保存的图片的大小
- getSupportedPictureFormats() 获取相机支持的图片格式
- setPictureFormat() 设置相机保存的图片格式
- getSupportedFocusModes() 获取相机支持的对焦模式
- setFocusMode(String value) 设置相机的对焦模式
- getMaxNumDetectedFaces() 返回相机最大的人脸检测数量
PreviewCallback
PreviewCallback 是一个抽象接口
-
void onPreviewFrame(byte[] data, Camera camera)
通过onPreviewFrame方法来获取到相机预览的数据,第一个参数data,就是相机预览到的原始数据。data可以转换图片做人脸检测
Face
Face类用来描述通过Camera的人脸检测功能检测到的人脸信息
- rect rect 是一个Rect对象,它所表示的就是检测到的人脸的区域
- score 人脸的可信度(0-100)
- leftEye 左眼位置坐标系
- rightEye 右眼位置坐标系
- mouth 眼睛位置坐标系
- leftEye rightEye mouth 都是 Point 对象 部分手机可能返回来为 null
FaceDetectionListener
抽象接口开始人脸检测的时候回调
- onFaceDetection(Face[] faces, Camera camera)
第一参数代表检测到的人脸,是一个Face数组(画面内可能存在多张人脸)
Camera类中的方法
- getNumberOfCameras()
返回当前设备上可用的摄像头个数 - open()
使用当前设备上第一个后置摄像头创建一个Camera对象。如果当前设备没有后置摄像头,则返回值为null - open(int cameraId)
使用传入id所表示的摄像头创建一个Camera对象,如果id所表示的摄像头已经被打开,则会抛出异常
设备上每一个物理摄像都是有一个id的,id从0开始,到getNumberOfCameras() - 1 结束
- getCameraInfo(int cameraId, CameraInfo cameraInfo)
返回指定id所表示的摄像头的信息 - setDisplayOrientation(int degrees)
设置相机预览画面旋转的角度 - setPreviewDisplay(SurfaceHolder holder)
设置一个Surface对象用来实时预览 - setPreviewCallback(PreviewCallback cb)
设置相机预览数据的回调,参数是一个PreviewCallback对象 - getParameters()
返回当前相机的参数信息,返回值是一个Parameters对象 - setParameters(Parameters params)
设置当前相机的参数信息 -
startPreview()
开始预览
调用此方法之前,如果没有setPreviewDisplay(SurfaceHolder) 或 setPreviewTexture(SurfaceTexture)的话,是没有效果 -
stopPreview()
停止预览 -
startFaceDetection()
开始人脸检测
这个方法必须在开始预览之后调用 -
stopFaceDetection()
停止人脸检测 -
setFaceDetectionListener(FaceDetectionListener listener)
设置人脸检测监听回调 -
release()
释放相机
第一章末尾