本文是阅读大神的文章https://www.jianshu.com/p/df3c8683bb90做的总结, 要学习Camera2请到原文中阅读
预览的步骤
完整相机预览需要以下几步
- 获取CameraId
- 创建用于显示预览图像的Surface
- openCamera
- 创建Session
- 创建Request
获取所有的CameraId
当然要首先获取到CameraId
private val cameraManager by lazy {
getSystemService(CameraManager::class.java) as CameraManager
}
获取到所有的CameraId
val cameraIdList = cameraManager.cameraIdList
logcat("cameraList:${
GsonManager.instance.toJson(cameraIdList)}")
for (id in cameraIdList) {
val character = cameraManager.getCameraCharacteristics(id)
if (character[CameraCharacteristics.LENS_FACING] == CameraCharacteristics.LENS_FACING_FRONT) {
logcat("is font:$id")
mFortCameraId = id
mFortCharacter = character
} else if (character[CameraCharacteristics.LENS_FACING] == CameraCharacteristics.LENS_FACING_BACK) {
logcat("is back:$id")
if (id == "0") {
mBackCameraId = id
mBackCharacter = character
}
}
}
这里我们强行给了一个id为0的id. 因为我发现摄像头背后一共有4个Camera. 他们的区别我们先不深究
创建Surface
这里我们使用TextureView. 在onCreate中调用
private fun loadPreview() {
binding.cameraPreview.surfaceTextureListener = object : TextureView.SurfaceTextureListener {
override fun onSurfaceTextureAvailable(
surface: SurfaceTexture?,
width: Int,
height: Int
) {
```````````
if (surface == null) return
logcat("onSurfaceTextureAvailable")
val previewSize = getOptimalSize(
mBackCharacter,
resources.displayMetrics.heightPixels,
resources.displayMetrics.widthPixels
) ?: return
logcat("cameraPreview:${
previewSize.width} ${
previewSize.height}")
surface.setDefaultBufferSize(previewSize.width, previewSize.height)
val lp = binding.cameraPreview.layoutParams
lp.width = previewSize.height
lp.height = previewSize.width
binding.cameraPreview.layoutParams = lp
mPreviewSurface = Surface(surface)
}
override fun onSurfaceTextureSizeChanged(
surface: SurfaceTexture?,
width: Int,
height: Int
) {
logcat("onSurfaceTextureSizeChanged")
}
override fun onSurfaceTextureDestroyed(surface: SurfaceTexture?): Boolean {
logcat("onSurfaceTextureDestroyed")
return true
}
override fun onSurfaceTextureUpdated(surface: SurfaceTexture?) {
// logcat("onSurfaceTextureUpdated")
}
}
}
openCamera
我们在onResume中进行openCamera的操作
cameraManager.openCamera(mBackCameraId, object : CameraDevice.StateCallback() {
override fun onOpened(camera: CameraDevice) {
logcat("onOpened")
mCameraDevice = camera
//打开Camera成功之后, 我们进行createSession的操作
mCameraDevice?.createCaptureSession(listOf(mPreviewSurface), mSessionStateCallback, mHandler)
}
override fun onDisconnected(camera: CameraDevice) {
logcat("onDisconnected")
camera.close()
}
override fun onClosed(camera: CameraDevice) {
super.onClosed(camera)
logcat("onClosed")
mCameraDevice = null
}
override fun onError(camera: CameraDevice, error: Int) {
logcat("onError")
camera.close()
}
}, mHandler)
创建Session
如上文, 我们在openCamera成功之后, 进行创建session的操作
mCameraDevice?.createCaptureSession(listOf(mPreviewSurface), mSessionStateCallback, mHandler)
创建Request
session创建成功之后, 我们在回调成功的时候, 发起capture request
private var mSessionStateCallback = object : CameraCaptureSession.StateCallback() {
override fun onConfigured(session: CameraCaptureSession) {
logcat("onSession coufigured")
}
override fun onConfigureFailed(session: CameraCaptureSession) {
logcat("onSession failed")
}
override fun onClosed(session: CameraCaptureSession) {
super.onClosed(session)
logcat("onSession closed")
}
override fun onReady(session: CameraCaptureSession) {
super.onReady(session)
logcat("onReady")
mSession = session
val camera = mCameraDevice ?: return
val requestBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)
requestBuilder.addTarget(mPreviewSurface)
val request = requestBuilder.build()
mSession.setRepeatingRequest(
request, object : CameraCaptureSession.CaptureCallback() {
override fun onCaptureStarted(session: CameraCaptureSession, request: CaptureRequest, timestamp: Long, frameNumber: Long) {
// logcat("onCaptureStarted")
}
override fun onCaptureProgressed(session: CameraCaptureSession, request: CaptureRequest, partialResult: CaptureResult) {
// logcat("onCaptureProgressed")
}
override fun onCaptureCompleted(session: CameraCaptureSession, request: CaptureRequest, result: TotalCaptureResult) {
// logcat("onCapturecompleted")
}
}, mHandler
)
}
}
至此, 可以完成预览了