【Android Camera1】Camera1源码分析【Java层】

2023-11-03 21:48

本文主要是介绍【Android Camera1】Camera1源码分析【Java层】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Camera1源码分析

  • 一、摘要
  • 二、内部类
    • 2.1 Area
      • 属性
    • 2.2 AutoFocusCallback
    • 2.3 AutoFocusMoveCallback
    • 2.4 CameraInfo
      • 2.4.1 facing
      • 2.4.2 orientation
      • 2.4.3 canDisableShutterSound
    • 2.5 ErrorCallback
    • 2.6 EventHandler
    • 2.7 Face 和 FaceDetectionListener
    • 2.8 IAppOpsCallbackWrapper
    • 2.9 OnZoomChangeListener
    • 2.10 Parameters
    • 2.11 PreviewCallback,PictureCallback,ShutterCallback
  • 三、变量
  • 三、初始化和销毁
    • 3.1 open
      • 3.1.1 open()
      • 3.1.2 Camera(int cameraId)
      • 3.1.3 int cameraInitNormal(int cameraId)
      • 3.1.4 int cameraInitNormal(int cameraId)
    • 3.2 startPreview
    • 3.3 stop and release
      • 3.3.1 stopPreview()
      • 3.3.1 release()
  • 四、参数设置
    • 4.1 读取和更新Parameters
      • 读取Parameters
      • 更新Parameters
    • 4.2 参数内容
  • 五、拍照

一、摘要

本篇文章介绍Camera1 Java应用层的源码,只涉及相关API说明以及使用场景,不涉及具体完整功能开发,具体可执行代码可参考Camera1开源项目分析。感兴趣的也可自行浏览Camera.Java类。 本篇文章分为如下几个部分讲解:

  • 内部类
  • 变量
  • 初始化和销毁
  • 参数设置
  • 拍照

二、内部类

内部类用法说明
Area1. 数据结构类:2.3A控制中,标记AF、AE的对焦区域和测光区域
AutoFocusCallback1. 接口; 2. 自动对焦【单词对焦模式】的回调接口
AutoFocusMoveCallback1. 接口; 2. 自动对焦【连续对焦模式】的回调接口
CameraInfo1.类;2. Camera基本信息
ErrorCallbackCamera发生错误回调接口
EventHandlerCamera事件分发线程Handle
Face人脸信息数据结构类
FaceDetectionListener人脸检测Listener
IAppOpsCallbackWrapperAudio状态变更回调
OnZoomChangeListenerZoom缩放Change回调
ParametersCamera 参数管理类
PictureCallback拍照回调
PreviewCallback预览回调
ShutterCallback拍照咔擦声音回调
SizeImage Size数据结构类

2.1 Area

Area主要涉及到对相机的3A控制自动对焦自动曝光自动白平衡流程。更详细的细节会在Camera1系列3A相关文章中进行阐述,这里只做简要介绍。3A算法的理论介绍可参看:Camera理论知识和基本原理

具体体现在代码实现层面,在Camera1中体现的数据结构类是Area。它承载了相机预览界面的区域以及该区域的权重。

  1. 自动对焦可根据对应区域进行对焦保证对应区域的画面清晰
  2. 自动曝光可根据对应区域进行测光来保证对应区域的曝光亮度是正常的

属性

  • rect :界定区域边界,范围为 [-1000,1000],是Camera1内部相机的坐标系

The bounds are relative to the camera’s current field of view. The coordinates are mapped so that (-1000, -1000) is top-left corner and (1000, 1000) is bottom-right corner. Bounds outside is not allowed. zero or negative width or height are not allowed.

  • weight : 该区域的权重,[1,1000] 在实际应用中基本都直接设为1000

The weight represents a weight for every pixel in the area. This means that a large metering area with the same weight as a smaller area will have more effect in the metering result. Metering areas can overlap and the driver will add the weights in the overlap region.

2.2 AutoFocusCallback

调用 mCamera.autoFocus(AutoFocusCallback)传入

void onAutoFocus(boolean success, Camera camera)

  • success表示自动对焦成功还是失败,可根据此字段来1.重试对焦;2.刷新UI;3.提示用户;4.统计等

说明:

  • autoFocus对焦仅限在FocusModo"auto-focus"的情况下使用,如果相机不支持该模式,则实际上是假生效。具体对焦模式可参考文章后方相关API

2.3 AutoFocusMoveCallback

void onAutoFocusMoving(boolean start, Camera camera);

  • 标志对焦的开始和结束
  • 在对焦模式为:FOCUS_MODE_CONTINUOUS_VIDEOFOCUS_MODE_CONTINUOUS_PICTURE时生效

2.4 CameraInfo

这是一个很重要的类,而且实际开发过程中的坑也很多,该类包含如下几个属性

2.4.1 facing

一半手机设备会存在前置摄像头后置摄像头2个。具体描述可参考Android Camera理论协议和规范里关于相机相关的协议。不同的App打开,会默认开启前置或者后置摄像头。

前置后置摄像头根据cameraId进行区分,一般情况下cameraId = 0为后置,cameraId = 1为前置。Camera1Camera2CameraX 关于摄像头方向的描述上有一定的概念差异,一定要进行区分。

CameraInfo类里有如下2个静态常量

/**
* The facing of the camera is opposite to that of the screen.
*/
public static final int CAMERA_FACING_BACK = 0;

/**
* The facing of the camera is the same as that of the screen.
*/
public static final int CAMERA_FACING_FRONT = 1;

注意这2个常量的注释。The facing of the camera is opposite to that of the screen 跟屏幕相反的方向以及The facing of the camera is the same as that of the screen. 跟屏幕相同的方向。这里是用跟屏幕的相同相反来进行区分,并不是明确的标志0->后置。 因为在折叠屏幕上,屏幕可折叠,正反面都是屏幕,这时或许需要单独考虑下差异性。

2.4.2 orientation

这也是经常会有坑的地方,众所周知大部分手机都是竖着的,即height > width 【不考虑折叠屏,PAD,分屏等情况】,通常相机后置frame流和手机方向会有90度的夹角,前置frame流和手机方向有270度的夹角。所以一般后置我们都要手动设置90。如:mCamera.setDisplayOrientation(90)。更直观的如下:
在这里插入图片描述
可以看到90度为正常的方向。

当然在实际的计算中,考虑到手机方向也会随着传感器变化,通常会计算最终的targetOrientation值,这里贴上官方Demo的计算函数:

 /*** Calculate display orientation
https://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation(int)*/private int calcDisplayOrientation() {CameraInfo info = new Camera.CameraInfo();android.hardware.Camera.getCameraInfo(cameraId, info);int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();int degrees = 0;switch (rotation) {case Surface.ROTATION_0: degrees = 0; break;case Surface.ROTATION_90: degrees = 90; break;case Surface.ROTATION_180: degrees = 180; break;case Surface.ROTATION_270: degrees = 270; break;}int result;if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {result = (info.orientation + degrees) % 360;result = (360 - result) % 360;  // compensate the mirror} else {  // back-facingresult = (info.orientation - degrees + 360) % 360;}camera.setDisplayOrientation(result);}

!!虽说大部分都遵循如上规则,但Android手机厂商,型号碎片化过多,有一些手机不遵循后置Frame和手机90度夹角的规则,如Nexus 6等手机,这种情况下就需要单独去做兼容处理

2.4.3 canDisableShutterSound

这个特性也是Camera1中特有的,也是经常会遇到坑的地方。在Camera1中拍照会有声音提示,该属性表示是否可以关闭声音提示。因此就会有如下坑:

  • 某些手机不能关闭声音提示如一些小米机型,就需要花费额外较大的成本去兼容这些机型
  • 通过Camera.getCameraInfo(cameraId, info);去获取相关字段值的时候,canDisableShutterSound和手机的Audio系统有关系。在某些手机上会抛异常,如果没有注意到这个异常将会导致相机功能不可用。因此对该字段的处理要更细致一些。具体我将在Camera1初始化文章中进行阐述

2.5 ErrorCallback

主要用来捕获相机执行过程中发生的一些错误情况,抛出具体的errorCode给开发人员
void onError(int error, Camera camera);。在实际开发一个健壮性比较高的Camera1能力应用App中,你将会在不同的Android机型发现各种奇奇怪怪的错误。

2.6 EventHandler

Handle类,所在的线程和初始化相机的业务线程保持一致。

2.7 Face 和 FaceDetectionListener

检测人脸相关类,通常在前置摄像头场景下开启,但会影响性能,实际应用场景不多。Face则是一个代表人脸信息的数据结构类,提供非常简单的人脸信息:

  • public Rect rect; [-1000,1000]
  • public int id = -1;
  • public Point leftEye = null;
  • Point rightEye = null;
  • public Point mouth = null;
  • public int score;

2.8 IAppOpsCallbackWrapper

该接口主要和canDisableShutterSound有关,实际会监听手机状态,动态更改canDisableShutterSound。实际应用场景很少,感兴趣的可参考,该类下的:private void updateAppOpsPlayAudio() 方法。

2.9 OnZoomChangeListener

Zoom值改变的时候通过回掉告诉上层当前缩放系数为多少,实际开发中很少用到 有如下接口:
void onZoomChange(int zoomValue, boolean stopped, Camera camera);

2.10 Parameters

四、参数设置模块进行详细阐述

2.11 PreviewCallback,PictureCallback,ShutterCallback

分辨对应相机开始预览时候的回掉,拍照时候的毁掉,和ShutterCallback用来提示用户快门声音,对应如下接口:

  • void onPreviewFrame(byte[] data, Camera camera);
  • void onPictureTaken(byte[] data, Camera camera);
  • void onShutter();

三、变量

变量名说明
CAMERA_MSG_ERRORMsg Code:Camera错误消息
CAMERA_MSG_SHUTTERMsg Code:Camera快门消息
CAMERA_MSG_FOCUSMsg Code:Camera对焦消息
CAMERA_MSG_ZOOMMsg Code:Camera缩放消息
CAMERA_MSG_PREVIEW_FRAMEMsg Code:Camera预览帧消息
CAMERA_MSG_VIDEO_FRAMEMsg Code:Camera视频帧消息
CAMERA_MSG_POSTVIEW_FRAMEMsg Code:Camera onPictureTaken消息
CAMERA_MSG_RAW_IMAGEMsg Code:Camera 拍照raw数据流消息
CAMERA_MSG_COMPRESSED_IMAGEMsg Code:Camera 拍照过程中compressed消息
CAMERA_MSG_RAW_IMAGE_NOTIFYMsg Code:Camera 拍照过程中完成拍照返Raw数据消息
CAMERA_MSG_PREVIEW_METADATAMsg Code:onFaceDetection消息
CAMERA_MSG_FOCUS_MOVEMsg Code:onAutoFocusMoving消息
mNativeContext上下文
mEventHandler/
mShutterCallback、mRawImageCallback、mJpegCallback、mPreviewCallback、mPostviewCallback预览拍照的回调接口
mAutoFocusCallback、mAutoFocusMoveCallback、mZoomListener、mFaceListener自动对焦,移动对焦,缩放,人脸检测回调
mErrorCallback、mDetailedErrorCallback错误处理回调
ACTION_NEW_PICTUREBroadcast Action: A new picture is taken by the camera, and the entry of the picture has been added to the media store.
ACTION_NEW_VIDEOBroadcast Action: A new video is recorded by the camera, and the entry of the video has been added to the media store.
CAMERA_FACE_DETECTION_HWHardware face detection. It does not use much CPU
CAMERA_FACE_DETECTION_SWSoftware face detection. It uses some CPU.

三、初始化和销毁

本节只介绍和初始化销毁相关的源码API。具体完善的初始化销毁代码可参考Camera1初始化销毁文章Camera1源码项目分析文章。和初始化销毁相关的核心函数如下:

函数
1.Camera(int cameraId)
2.cameraInitNormal(int cameraId)
3.cameraInitVersion(int cameraId, int halVersion)
4.native final int native_setup(Object camera_this, int cameraId, int halVersion, String packageName)
5.Camera open()
6.Camera open(int cameraId)
7.native final void startPreview();
8.void stopPreview()
9.native final void _stopPreview()
10. void release()
11. native final void native_release();
12. void releaseAppOps()

以上函数可归纳为如下4个模块,每个模块最后的函数调用都指向native函数。

模块
open
startPreview
stopPreview
release

3.1 open

执行顺序为 5 -> 6 -> 1 -> 2 -> 3 -> 4

3.1.1 open()

    public static Camera open() {int numberOfCameras = getNumberOfCameras();CameraInfo cameraInfo = new CameraInfo();for (int i = 0; i < numberOfCameras; i++) {getCameraInfo(i, cameraInfo);if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {return new Camera(i);}}return null;}
  1. native static int getNumberOfCameras();native获取手机相机的数目。
  2. getCameraInfo(i, cameraInfo); 获取对应cameraId的cameraInfo ->【 2.4.1】
  3. 默认初始化后置CameraInfo.CAMERA_FACING_BACK

3.1.2 Camera(int cameraId)

    Camera(int cameraId) {int err = cameraInitNormal(cameraId);if (checkInitErrors(err)) {if (err == -EACCES) {throw new RuntimeException("Fail to connect to camera service");} else if (err == -ENODEV) {throw new RuntimeException("Camera initialization failed");}// Should never hit this.throw new RuntimeException("Unknown camera error");}initAppOps();}
  1. cameraInitNormal(cameraId); ->【3.1.3】
  2. 处理异常错误,注意这里只单独识别了-EACCES-ENODEV错误信息
  3. initAppOps(); 处理canDisableShutterSound 实际场景接触几乎没有,其他可参考-> 2.4.3,2.8

3.1.3 int cameraInitNormal(int cameraId)

private int cameraInitNormal(int cameraId) {return cameraInitVersion(cameraId, CAMERA_HAL_API_VERSION_NORMAL_CONNECT);}
  1. CAMERA_HAL_API_VERSION_NORMAL_CONNECT 为HAL的版本号有如下3个版本号,了解即可,开发场景不会遇到。
    /*** Camera HAL device API version 1.0* @hide*/@UnsupportedAppUsagepublic static final int CAMERA_HAL_API_VERSION_1_0 = 0x100;/*** A constant meaning the normal camera connect/open will be used.*/private static final int CAMERA_HAL_API_VERSION_NORMAL_CONNECT = -2;/*** Used to indicate HAL version un-specified.*/private static final int CAMERA_HAL_API_VERSION_UNSPECIFIED = -1;

3.1.4 int cameraInitNormal(int cameraId)

    private int cameraInitVersion(int cameraId, int halVersion) {mShutterCallback = null;mRawImageCallback = null;mJpegCallback = null;mPreviewCallback = null;mPostviewCallback = null;mUsingPreviewAllocation = false;mZoomListener = null;Looper looper;if ((looper = Looper.myLooper()) != null) {mEventHandler = new EventHandler(this, looper);} else if ((looper = Looper.getMainLooper()) != null) {mEventHandler = new EventHandler(this, looper);} else {mEventHandler = null;}return native_setup(new WeakReference<Camera>(this), cameraId, halVersion,ActivityThread.currentOpPackageName());}
  1. 重置变量 ->【三】
  2. 初始化mEventHandle 这里要注意,camera1流程消息队列和使用Camera相机能力业务保持一致
  3. native_setup native 函数调用。其参数是Camera.java实例类,cameraIdhal版本号packageName

3.2 startPreview


1. capture,drawing preview frames
2. 需要surface
*************/*** Starts capturing and drawing preview frames to the screen.* Preview will not actually start until a surface is supplied* with {@link #setPreviewDisplay(SurfaceHolder)} or* {@link #setPreviewTexture(SurfaceTexture)}.**/
相关函数常用的如1
1.setPreviewCallback(Camera.PreviewCallback)      
*************/** <p>If {@link #setPreviewCallback(Camera.PreviewCallback)},* {@link #setOneShotPreviewCallback(Camera.PreviewCallback)}, or* {@link #setPreviewCallbackWithBuffer(Camera.PreviewCallback)} were* called, {@link Camera.PreviewCallback#onPreviewFrame(byte[], Camera)}* will be called when preview data becomes available.
**/
异常处理
1. 硬件错误
2. 设备兼容性错误
3. startPreview时发现camera is release
4. connect fail
5. previewSize设置不对
6. pictureSize设置不对
7. 其他
以上的没一种错误都会影响用户的实际体验,因此好的应用就需要用各种方式解决如上错误。详细可参考Camera1初始化文章
*************/** @throws RuntimeException if starting preview fails; usually this would be*    because of a hardware or other low-level error, or because release()*    has been called on this Camera instance. The QCIF (176x144) exception*    mentioned in {@link Parameters#setPreviewSize setPreviewSize} and*    {@link Parameters#setPictureSize setPictureSize} can also cause this*    exception be thrown.*/public native final void startPreview();

3.3 stop and release

stoprelease流程经常放在一起,常见的场景如下:

  1. 切前后台
  2. 切前后置
  3. 切画幅
  4. 切拍照和视频模式
  5. 切页面

执行顺序:8 -> 9 -> 10 -> 11

3.3.1 stopPreview()

同样需要特别注意异常捕获和处理
**************/*** Stops capturing and drawing preview frames to the surface, and* resets the camera for a future call to {@link #startPreview()}.** @throws RuntimeException if stopping preview fails; usually this would be*    because of a hardware or other low-level error, or because release()*    has been called on this Camera instance.*/public final void stopPreview() {_stopPreview();mFaceDetectionRunning = false;mShutterCallback = null;mRawImageCallback = null;mPostviewCallback = null;mJpegCallback = null;synchronized (mAutoFocusCallbackLock) {mAutoFocusCallback = null;}mAutoFocusMoveCallback = null;}private native final void _stopPreview();

3.3.1 release()

断开和camera的链接以及释放资源

 /*** Disconnects and releases the Camera object resources.** <p>You must call this as soon as you're done with the Camera object.</p>*/public final void release() {native_release();mFaceDetectionRunning = false;releaseAppOps();}private native final void native_release();

四、参数设置

Camera1所有的参数设置都将通过Parameters

4.1 读取和更新Parameters

主要涉及到2个函数。

  • public Parameters getParameters()
  • public void setParameters(Parameters params)
  /*** Returns the current settings for this Camera service.* @throws RuntimeException if reading parameters fails; usually this would*    be because of a hardware or other low-level error, or because*    release() has been called on this Camera instance.* @see #setParameters(Camera.Parameters)*/public Parameters getParameters() {Parameters p = new Parameters();String s = native_getParameters();p.unflatten(s);return p;}/*** Changes the settings for this Camera service.** @param params the Parameters to use for this Camera service* @throws RuntimeException if any parameter is invalid or not supported.* @see #getParameters()*/public void setParameters(Parameters params) {// If using preview allocations, don't allow preview size changesif (mUsingPreviewAllocation) {Size newPreviewSize = params.getPreviewSize();Size currentPreviewSize = getParameters().getPreviewSize();if (newPreviewSize.width != currentPreviewSize.width ||newPreviewSize.height != currentPreviewSize.height) {throw new IllegalStateException("Cannot change preview size" +" while a preview allocation is configured.");}}native_setParameters(params.flatten());}

代码如上,这里尤其要注意以下问题:

  • 参数读取和设置不影响相机功能
  • 但是参数读取和设置都会抛异常

在实际开发使用一定要单独包装2个函数:

读取Parameters

  public static @Nullable Camera.Parameters getCameraParameters(@NonNull Camera camera) {try {return camera.getParameters();}catch (Exception e){return null;}}	
  • getCameraParameters要保证传入的camera实例不为null
  • getCameraParameters会返回null需要对返回值做处理

更新Parameters

    public static boolean setCameraParameters(@NonNull Camera camera, @NonNull Camera.Parameters parameters) {try {camera.setParameters(parameters);return true;}catch (Exception e){return false;}}

同样需要保证传入参数的正确性,以及对返回值进行处理。

4.2 参数内容

本节只是简要说明具体的参数项,不会特殊去阐述每个设置的效果,如需了解,请参看Camera1系列文章之参数设置一文。Parameters里有一个Map存放对应的Key->Value。该类的方法函数也是获取对应Key的Value值,感兴趣的可自行浏览源码,这里就不重复阐述了。

以下以红米note9为机型获取到的具体参数值,意识可按照属性value字面意思理解即可。实际的效用,可参看Camera1系列文章之参数设置。

Key变量名Key变量值Value值说明
KEY_PREVIEW_SIZEpreview-size1440x1080预览尺寸;【1440x1080 1920x1080,1600x960…】
KEY_PREVIEW_FORMATpreview-formatyuv420sp预览格式;【yuv420p,yuv420sp,yuv420p】
KEY_PREVIEW_FRAME_RATEpreview-frame-rate30当前预览帧率【10,15,20,30】
KEY_PREVIEW_FPS_RANGEpreview-fps-range5000,300005,30
KEY_PICTURE_SIZEpicture-size3264x2448照片尺寸:【4000x2992,4000x2240,4000x1808… 】
KEY_PICTURE_FORMATpicture-formatjpeg范围:【jpeg】
KEY_JPEG_THUMBNAIL_SIZEjpeg-thumbnail-size250,187范围:【0x0,160x96,162x121,192x108…】
KEY_JPEG_THUMBNAIL_WIDTHjpeg-thumbnail-width250/
KEY_JPEG_THUMBNAIL_HEIGHTjpeg-thumbnail-height187/
KEY_JPEG_THUMBNAIL_QUALITYjpeg-thumbnail-quality90缩略图质量
KEY_JPEG_QUALITYjpeg-quality90takePic图片质量
KEY_ROTATIONrotation90/
KEY_GPS_LATITUDEgps-latitude/gps信息
KEY_GPS_LONGITUDEgps-longitude/gps信息
KEY_GPS_ALTITUDEgps-altitude/gps信息
KEY_GPS_TIMESTAMPgps-timestamp/gps信息
KEY_GPS_PROCESSING_METHODgps-processing-method//
KEY_WHITE_BALANCEwhitebalanceauto【auto,incandescent,fluorescent,warm-fluorescent,daylight,cloudy-daylight,twilight,shade】
KEY_EFFECTeffectnone【none】
KEY_ANTIBANDINGantibandingauto【off,50hz,60hz,auto】
KEY_SCENE_MODEscene-modeauto【auto,action,portrait,landscape,night,night-portrait,theatre,beach,snow,sunset,steadyphoto,fireworks,sports,party,candlelight,barcode,hdr】
KEY_FLASH_MODEflash-modeauto【off,auto,on,torc】和刷新率有关系,例如刷新率不对会出现摩尔纹等问题
KEY_FOCUS_MODEfocus-modecontinuous-picture【auto,macro,continuous-video,continuous-picture】
KEY_FOCUS_AREASfocus-areas(0,0,0,0,0)对焦区域
KEY_MAX_NUM_FOCUS_AREASmax-num-focus-areas1支持最大的对焦区域个数
KEY_FOCAL_LENGTHfocal-length4.695
KEY_HORIZONTAL_VIEW_ANGLEhorizontal-view-angle68.5548
KEY_VERTICAL_VIEW_ANGLEvertical-view-angle54.1506
KEY_EXPOSURE_COMPENSATIONexposure-compensation0
KEY_MAX_EXPOSURE_COMPENSATIONmax-exposure-compensation24
KEY_MIN_EXPOSURE_COMPENSATIONmin-exposure-compensation-24
KEY_EXPOSURE_COMPENSATION_STEPexposure-compensation-step0.166667实际曝光值需要step*exposure-compensation值
KEY_AUTO_EXPOSURE_LOCKauto-exposure-lockfalse
KEY_AUTO_EXPOSURE_LOCK_SUPPORTEDauto-exposure-lock-supportedtrue
KEY_AUTO_WHITEBALANCE_LOCKauto-whitebalance-lockfalse
KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTEDauto-whitebalance-lock-supportedtrue
KEY_METERING_AREASmetering-areas(0,0,0,0,0)
KEY_MAX_NUM_METERING_AREASmax-num-metering-areas1
KEY_ZOOMzoom0
KEY_MAX_ZOOMmax-zoom991 - 99 99个刻度映射到实际摄像头的zoom
KEY_ZOOM_RATIOSzoom-ratios100~999对应1f - 9.99f
KEY_ZOOM_SUPPORTEDzoom-supportedtrue
KEY_SMOOTH_ZOOM_SUPPORTEDsmooth-zoom-supportedfalse
KEY_FOCUS_DISTANCESfocus-distancesInfinity,Infinity,Infinity
KEY_VIDEO_SIZEvideo-size1920x10803840x2160,2400x1080,2340x1080…
KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEOpreferred-preview-size-for-video1920x1080
KEY_MAX_NUM_DETECTED_FACES_HWmax-num-detected-faces-hw15
KEY_MAX_NUM_DETECTED_FACES_SWmax-num-detected-faces-sw0
KEY_RECORDING_HINTrecording-hintfalse录制提示
KEY_VIDEO_SNAPSHOT_SUPPORTEDvideo-snapshot-supportedfalse
KEY_VIDEO_STABILIZATIONvideo-stabilizationfalsetrue 也实际没啥用
KEY_VIDEO_STABILIZATION_SUPPORTEDvideo-stabilization-supportedtrue

五、拍照

源码API提供的函数基本上就是直接调用native函数,传入回调函数。实际的用法其实比较复杂,具体细节可参看Camera1系列文章之拍照

   /*** Equivalent to <pre>takePicture(Shutter, raw, null, jpeg)</pre>.** @see #takePicture(ShutterCallback, PictureCallback, PictureCallback, PictureCallback)*/public final void takePicture(ShutterCallback shutter, PictureCallback raw,PictureCallback jpeg) {takePicture(shutter, raw, null, jpeg);}private native final void native_takePicture(int msgType);

这篇关于【Android Camera1】Camera1源码分析【Java层】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/341080

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听