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)
        }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章