相机配置
初始化配置:¶
内部原理:
ManagerConfig
类持有了相机的各类功能参数,
在构造CameraXFragment时由构造函数将配置类(ManagerConfig
)传入。
cameraXFragment = CameraXFragment.newInstance(
//相机的初始化配置
cameraConfig,
//设置初始化事件监听
eventListener = this,
//拍照录视频操作结果通知回调
captureResultListener = this
)
Note
在通过BaseCameraXActivity
实现自定义相机时,可以重写configAll方法,自定义相机配置
在通过BaseCameraXFragment
实现自定义相机时,直接由构造函数传入即可。
示例CameraExampleActivity 中的配置方式¶
BaseCameraXActivity
类定义了一个configAll
方法,它接收传入的intent,并返回相机配置(ManagerConfig)
通过继承BaseCameraXActivity
实现自定义相机时,需要重写configAll方法,生成相机配置(ManagerConfig)。
intent参数来自于你调用startActivity时的传入,与本库无关,你不用intent传参可以忽略这个参数。
class CameraExampleActivity : BaseCameraXActivity() {
// CameraExampleActivity中通过重写configAll 可配置相机一些内容
// 接收到intent,对相机进行配置
override fun configAll(intent: Intent): ManagerConfig {
//视频录制配置(可选)
val videoRecordConfig = VideoRecordConfig(
quality = CameraRecordQuality.HD,//设置视频拍摄质量
// fileSizeLimit=100.mb, //文件大小限制。
// durationLimitMillis =1000*15, //录制时长限制,单位毫秒
//...省略
)
//拍照配置(可选)
val imageCaptureConfig =ImageCaptureConfig(
horizontalMirrorMode= MirrorMode.MIRROR_MODE_ON_FRONT_ONLY, //水平翻转
verticalMirrorMode = MirrorMode.MIRROR_MODE_ON_FRONT_ONLY, //垂直翻转
//...省略
)
val useImageDetection = intent.getBooleanExtra(ImageDetection, false) //是否使用图像分析
//构建相机配置并返回
return ManagerConfig().apply { //return 相机配置实例
this.recordConfig = videoRecordConfig
//这里指定了打开相机时的默认用例模式,图像分析、拍照、录像等。其实就是指定相机的用例组合
this.useCaseMode =
if (useImageDetection) UseCaseMode.imageAnalysis else UseCaseMode.takePhoto
//闪光灯配置
this.flashMode = FlashModel.CAMERA_FLASH_AUTO
//android R以下时,在少数display为null的情况下,设置预览,拍照的默认分辨率
this.size = Size(1920, 1080)
}
}
}
示例CameraExampleActivity2 中的配置方式¶
通过BaseCameraXFragment
实现自定义相机,没有上面那样的configAll方法,毕竟你需要手动生成承载相机的fragment,以及将它放入合适的布局中。
你可以自己定义一个方法用于生成配置内容,以及接收intent传入,生成相机配置(ManagerConfig)。
最终,在承载相机功能的BaseCameraXFragment
的newInstance
方法中传入配置即可。
class CameraExampleActivity2 : AppCompatActivity(), CameraXFragmentEventListener,
CaptureResultListener {
lateinit var cameraConfig: ManagerConfig
var cameraXFragment: BaseCameraXFragment? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_fragment_container)
cameraConfig = parse(intent)//例如从intent中接受配置,构造出ManagerConfig
//这里,生成了承载相机的fragment,并将其放入合适的布局中
cameraXFragment = BaseCameraXFragment.newInstance(
cameraConfig, //将配置传入
//设置初始化事件监听
eventListener = this,
//拍照录视频操作结果通知回调
captureResultListener = this
)
supportFragmentManager.beginTransaction()
.replace(com.kiylx.camerax_lib.R.id.fragment_container, cameraXFragment!!).commit()
}
//解析intent,或其他什么,生成相机配置(ManagerConfig)并返回
fun parse(intent:Intent):ManagerConfig{
return ManagerConfig().apply { //return 相机配置实例
//这里指定了打开相机时的默认用例模式,图像分析、拍照、录像等。其实就是指定相机的用例组合
this.useCaseMode = UseCaseMode.takePhoto
//闪光灯配置
this.flashMode = FlashModel.CAMERA_FLASH_AUTO
//android R以下时,在少数display为null的情况下,设置预览,拍照的默认分辨率
this.size = Size(1920, 1080)
}
}
}
用例模式¶
我们在上面配置相机时,示例代码中可以配置相机启动时的用例模式,比如以拍照模式启动,以图像分析模式启动。其实就是在指定用例组合
- 配置相机启动时的用例模式
我们有如下几种用例组合方式,可直接用于配置ManagerConfig中的useCaseBundle字段,还可以调用UseCaseMode.customGroup
方法自定义用例组合,
自定义用例组合,例如:
return ManagerConfig().apply {
this.recordConfig = videoRecordConfig
this.useCaseMode = //通过调用UseCaseMode.customGroup方法自定义了一个可以预览,录像,图像分析的用例组合
UseCaseMode.customGroup(
UseCaseHexStatus.USE_CASE_PREVIEW,
UseCaseHexStatus.USE_CASE_IMAGE_ANALYZE,
UseCaseHexStatus.USE_CASE_VIDEO_CAPTURE
)
this.flashMode = FlashModel.CAMERA_FLASH_AUTO
//android R以下时,在少数display为null的情况下,设置预览,拍照的默认分辨率
this.size = Size(1920, 1080)
}
但注意,有些组合是不支持的
预定义的用例组合
val takePhoto = customGroup(
UseCaseHexStatus.USE_CASE_PREVIEW,
UseCaseHexStatus.USE_CASE_IMAGE_CAPTURE,
)
val takeVideo = customGroup(
UseCaseHexStatus.USE_CASE_PREVIEW,
UseCaseHexStatus.USE_CASE_VIDEO_CAPTURE,
)
val imageAnalysis = customGroup(
UseCaseHexStatus.USE_CASE_PREVIEW,
UseCaseHexStatus.USE_CASE_IMAGE_ANALYZE,
UseCaseHexStatus.USE_CASE_IMAGE_CAPTURE,
)
/**
* 除了预览画面用例,不使用其他任何用例
*/
const val onlyPreview = UseCaseHexStatus.USE_CASE_PREVIEW
除了ManagerConfig中useCaseBundle指定相机启动时的默认用例模式,还可以通调用cameraXFragment
中的setCameraUseCase
方法来动态修改相机的用例组合
示例:录制完视频之后,将相机切换到拍照
/** 录完视频 */
override fun onVideoRecorded(saveFileData: SaveFileData?) {
super.onVideoRecorded(saveFileData)
cameraXF.setCameraUseCase(UseCaseMode.takePhoto) //动态切换相机用例
}
按下音量键拍照¶
如果使用的是CameraExampleActivity2,你可以复制如下代码到CameraExampleActivity2实现按下音量键拍照
/**
* 音量减按钮触发拍照,如果需要复制这份代码就可以
*
* When key down event is triggered, relay it via local broadcast so
* fragments can handle it
*/
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
return when (keyCode) {
KeyEvent.KEYCODE_VOLUME_DOWN -> {
val intent = Intent(KEY_CAMERA_EVENT_ACTION).apply {
putExtra(
KEY_CAMERA_EVENT_EXTRA,
keyCode
)
}
LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
true
}
else -> super.onKeyDown(keyCode, event)
}
}
ManagerConfig
类:¶
data class ManagerConfig(
var flashMode: Int = FlashModel.CAMERA_FLASH_OFF,
/**
* android R以下时,在少数display为null的情况下,设置预览,拍照的默认分辨率
*/
var size: Size = Size(1280, 720),
/** 指定这次相机使用的用例,例如拍照,录像,图像识别等 查看[UseCaseMode] */
var useCaseMode: Int = UseCaseMode.takePhoto,
/**
* 指定图像分析、拍照、录制的旋转角度,默认可能为[Surface.ROTATION_0]。 默认值是根据display的旋转方向而定
* 因此,如果在此指定值,默认值将不会使用
*/
var rotation: Int = -1,
/** 视频录制配置 */
var recordConfig: VideoRecordConfig = VideoRecordConfig(),
/** 拍照配置 */
var imageCaptureConfig: ImageCaptureConfig = ImageCaptureConfig()
)
VideoRecordConfig类:¶
data class VideoRecordConfig(
/**
* 设置用于录制的预期视频编码比特率。
* 目标视频编码比特率尝试使实际视频编码比特率接近请求的比特率。比特率在录制过程中可能会有所不同,具体取决于录制的场景。
* 将对请求的比特率进行额外的检查,以确保指定的比特率适用,有时传递的比特率会在内部更改,以确保视频录制可以根据平台的功能顺利进行。
* 此 API 仅影响视频流,不应被视为整个录制的目标。音频流的比特率不受此 API 的影响。
* 如果未调用此方法(此处不进行修改,还是0的状态下),则默认选择适当的比特率进行普通视频录制。仅当需要自定义比特率时才调用此方法。
*/
var encodingBitRate: Int = 0,
/**
* 默认位置信息
* Sets a Location object representing a geographic location where the video was recorded.
* When use with Recorder, the geographic location is stored in udta box if the output format is MP4, and is ignored for other formats. The geographic location is stored according to ISO-6709 standard.
* If null, no location information will be saved with the video. Default value is null.
*/
var location: Location? = null,
/**
* 录制时长
* Sets the limit for the video duration in milliseconds.
* When used to generate recording with Recorder, if the specified duration limit is reached while the recording is being recorded, the recording will be finalized with VideoRecordEvent.Finalize.ERROR_DURATION_LIMIT_REACHED.
* If not set or set with zero, the duration will be unlimited. If set with a negative value, an IllegalArgumentException will be thrown.
*/
var durationLimitMillis: Long = 0,
/**
* 文件大小限制,为0无限制
* Sets the limit for the file length in bytes.
* When used with Recorder to generate recording, if the specified file size limit is reached while the recording is being recorded, the recording will be finalized with VideoRecordEvent.Finalize.ERROR_FILE_SIZE_LIMIT_REACHED.
* If not set or set with zero, the file size will be unlimited. If set with a negative value, an IllegalArgumentException will be thrown.
*/
var fileSizeLimit: DataSize = 0.kb,
/**
* 视频录制质量,查看[CameraRecordQuality],当设置的视频拍摄质量不支持时,将会自动寻找支持的最高质量
*/
var quality: Int = CameraRecordQuality.HD,
/**
* 镜像设置
*/
var mirrorMode: Int = MirrorMode.MIRROR_MODE_ON_FRONT_ONLY,
) : Parcelable
ImageCaptureConfig类:¶
data class ImageCaptureConfig(
/**
* 水平翻转
*/
var horizontalMirrorMode: Int = MirrorMode.MIRROR_MODE_ON_FRONT_ONLY,
/**
* 垂直翻转
*/
var verticalMirrorMode: Int = MirrorMode.MIRROR_MODE_ON_FRONT_ONLY,
/**
* 默认位置信息
* Sets a Location object representing a geographic location where the video was recorded.
* When use with Recorder, the geographic location is stored in udta box if the output format is MP4, and is ignored for other formats. The geographic location is stored according to ISO-6709 standard.
* If null, no location information will be saved with the video. Default value is null.
*/
var location: Location? = null,
/**
* jpeg quality
* @IntRange(from = 1, to = 100)
*/
var jpegQuality: Int = 100,
/**
* [ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY]:缩短图片拍摄的延迟时间。
* [ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY]:提高图片拍摄的图片质量。
* 如果设备不符合最低要求,CameraX 便会回退到 CAPTURE_MODE_MINIMIZE_LATENCY。
*
* 零快门延迟仅适用于图片拍摄用例。无法为视频拍摄用例或相机扩展程序启用该功能。
* 由于使用闪光灯会增加延迟时间,因此当闪光灯开启或处于自动模式时,零快门延迟将不起作用。
*/
var captureMode:Int =ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY
) : Parcelable