Android如何使用Camera2拍照【简易快速上手篇】

因为大部分的需求,并没有那么复杂,只需要简单的拍照功能,对于这种简单的需求,本文可以很好的满足。本文,是对Camera2做一个极简易的封装,以及去掉其它不重要的API,帮助你在几分钟内,使用Camera2实现拍照功能。一共4个文件,直接复制粘贴就可以运行了。有什么问题,可以留下评论。

  • MainActivity.kt 文件
class MainActivity : AppCompatActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
     
        // 创建一个TextureView用于摄影机的预览
       val textureView = TextureView(this)
        // 设置TextureView加载进度监听
        textureView.setOnSurfaceTextureAvailable { surface, width, height ->
            // 当TextureView加载完成后, 会调用该方法。
            // 此时,可以打开摄影头,开始预览
            CameraUtils.openFrontCamera(CameraUtils.getCameraManager(this), textureView) {
                // 打开摄影头成功,设置点击事件
                textureView.setOnClickListener {
                    // 点击屏幕,拍照。
                    // textureView.bitmap就是Bitmap图。
                    // toImageView用于将bitmap转成ImageView用来展示。
                    setContentView(textureView.bitmap.toImageView(this))
                }
            }
        }

        // 将TextureView做为布局使用
        setContentView(textureView)
    }
    
}

这里面,注释齐全,接下来,看一下工具类的实现:

  • CameraUtils.kt 文件
/**
 * @date 创建时间:2020/4/22 11:54
 * @author Lyf
 * @description 用于简化摄影头的操作
 */
object CameraUtils {

    fun getCameraManager(context: Context) =
        context.getSystemService(Context.CAMERA_SERVICE) as CameraManager

    @SuppressLint("MissingPermission")
    fun openFrontCamera(
        cameraManager: CameraManager,
        textureView: TextureView,
        onError: (CameraDevice, Int) -> Unit = { _: CameraDevice, _: Int -> },
        onOpened: (CameraDevice) -> Unit = {}
    ) {

        cameraManager.openCamera(cameraManager.cameraIdList[0], object :
            CameraDevice.StateCallback() {
            override fun onOpened(camera: CameraDevice) {

                val targets = listOf(Surface(textureView.surfaceTexture))
                camera.createCaptureSession(
                    targets, object : CameraCaptureSession.StateCallback() {
                        override fun onConfigureFailed(session: CameraCaptureSession) {
                        }

                        override fun onConfigured(session: CameraCaptureSession) {

                            session.setRepeatingRequest(
                                camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)
                                    .apply { addTarget(Surface(textureView.surfaceTexture)) }
                                    .build(),
                                null,
                                null
                            )

                            onOpened.invoke(camera)
                        }

                    },
                    null
                )
            }

            override fun onDisconnected(camera: CameraDevice) {

            }

            override fun onError(camera: CameraDevice, error: Int) {
                onError.invoke(camera, error)
            }

        }, null)
    }

    fun captureBitmap(textureView: TextureView, callback: (Bitmap) -> Unit) {
        callback.invoke(textureView.bitmap)
    }
}
  • TextureViewExt.kt 文件
/**
 * @date 创建时间:2020/4/22 14:05
 * @author Lyf
 * @description 简化监听回调
 */
fun TextureView.setOnSurfaceTextureAvailable(callback: (surface: SurfaceTexture?, width: Int, height: Int) -> Unit) {

    this.surfaceTextureListener = object : TextureView.SurfaceTextureListener {
        override fun onSurfaceTextureSizeChanged(
            surface: SurfaceTexture?,
            width: Int,
            height: Int
        ) {

        }

        override fun onSurfaceTextureUpdated(surface: SurfaceTexture?) {

        }

        override fun onSurfaceTextureDestroyed(surface: SurfaceTexture?): Boolean {
            return true
        }

        override fun onSurfaceTextureAvailable(surface: SurfaceTexture?, width: Int, height: Int) {
            callback.invoke(surface, width, height)
        }

    }
}
  • BitmapExt.kt 文件
/**
 * @date 创建时间:2020/4/22 14:00
 * @author Lyf
 * @description Bitmap转ImageView
 */
fun Bitmap.toImageView(context: Context): ImageView {

    return ImageView(context)
        .also {
            it.layoutParams = ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT
            )
            it.scaleType = ImageView.ScaleType.FIT_XY
            it.setImageBitmap(this)
        }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章