AndroidはSurface Viewを使用してカメラプレビュー画面をロード

16459 ワード

Surface Viewを使用したカメラプレビューインタフェースのロード
1、カメラ権限の追加
   <uses-permission android:name="android.permission.CAMERA" />

2、ページレイアウト、私のプロジェクトに必要なのはスキャンページなので、下のレイアウトの下にSurface Viewを埋めました.
    <SurfaceView
        android:id="@+id/mSurfaceView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <ImageView
        android:id="@+id/view2"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_margin="60dp"
        android:background="@drawable/rpa_huli_rzpz_bianjiao_icon"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintDimensionRatio="h,16:10"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/face_confirm"
        android:layout_width="@dimen/public_120_dp"
        android:layout_height="@dimen/public_60_dp"
        android:layout_marginTop="136dp"
        android:background="@color/detail_bu"
        android:text="  "
        android:textColor="@color/white"
        android:textSize="24sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/view2" />

3,SurfaceHolder.callbackのカメラプレビュー機能のオン/オフを設定します.

    private val cpHolderCallback: SurfaceHolder.Callback = object : SurfaceHolder.Callback {
        override fun surfaceCreated(holder: SurfaceHolder) {
            camera?.setPreviewDisplay(holder)
            preview()//    
        }
        override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int)       {}
        override fun surfaceDestroyed(holder: SurfaceHolder) {
            stopPreview()//    
        }
    }

4、カメラデータの初期化、カメラプレビューのロード
  runOnUiThread {
            camera = Camera.open(0)
            try {
                val parameters: Camera.Parameters = camera!!.parameters
                parameters.pictureFormat = ImageFormat.JPEG//      
                //        ,FOCUS_MODE_CONTINUOUS_PICTURE      
                parameters.focusMode = Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE
                //       ,              
                val display = windowManager.defaultDisplay
                val height = display.height
                val width = display.width
                val preSize: Camera.Size =
                    CameraUtils.getCloselyPreSize(true, width,height,
                        parameters.supportedPreviewSizes)
                parameters.setPictureSize(preSize.width, preSize.height)
                camera!!.run {
                    setParameters(parameters)
                    setPreviewDisplay(mSurfaceView.holder)
                    //             90   
                    setDisplayOrientation(90)
                    startPreview()
                    cancelAutoFocus()
                }
                safeToTakePicture = true
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }

5、スキャンボタンを傍受して、画像を取得します.ここはプレビューインタフェースなので、普段のカメラの撮影方法とは少し違います.takePicture関数を使用する必要があります.3つのパラメータは画像コールバックを使用しました.画像を得る必要があるからです.
 face_confirm.setOnClickListener {
     camera?.takePicture(null, null, Camera.PictureCallback { data, _ ->
                    //data ByteArray   ,                     
                    pictureDataBytes = data
                    stopPreview()//             
              ...
                    }).start()
                })
 }

6,ByteArray変換String関数は,ピクチャのパッチアドレスを取得する.
   private fun PictureConversion(bytes: ByteArray?): String? {
        try {
            val f: File = File.createTempFile("img", ".jpg")
            val fos = FileOutputStream(f)
            fos.write(bytes)
            fos.flush()
            fos.close()
            return f.getAbsolutePath()
        } catch (e: IOException) {
            e.printStackTrace()
        }
        return ""
    }