SurfaceView之Android Camera预览
程序员文章站
2022-03-29 19:09:10
...
目录
前言
最近在研究OpenGL ES,发现关于Camera的基础部分还没理清楚,于是抱着打地基的态度先来弄下Camera以SurfaceView为载体的预览。这里只讲使用,原来比较复杂,后续有机会再补充。废话不多说马上进入正文。
正文
SurfaceView类的创建。
package com.example.mytest.camera
import android.content.Context
import android.graphics.ImageFormat
import android.hardware.Camera
import android.util.AttributeSet
import android.util.Log
import android.view.SurfaceHolder
import android.view.SurfaceView
class MySurfaceView(context: Context) : SurfaceView(context), SurfaceHolder.Callback {
private val mCameraIndex: Int = Camera.CameraInfo.CAMERA_FACING_BACK
//定义摄像机
private var camera: Camera? = null
//定义Camera的回调方法
private val previewCallback: Camera.PreviewCallback = object : Camera.PreviewCallback {
override fun onPreviewFrame(bytes: ByteArray, camera: Camera) {
// TODO
}
}
init {
//加入SurfaceHolder.Callback在类中implements
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
//保持屏幕常亮
holder.setKeepScreenOn(true);
}
override fun surfaceCreated(holder: SurfaceHolder) {
startCamera(mCameraIndex)
}
override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {}
override fun surfaceDestroyed(holder: SurfaceHolder) {
stopCamera()
}
//开启摄像机
private fun startCamera(mCameraIndex: Int) {
// 初始化并打开摄像头
// if (camera == null) {
try {
camera = Camera.open(mCameraIndex)
} catch (e: Exception) {
return
}
//获取Camera参数
val params: Camera.Parameters = camera!!.getParameters()
if (params.getSupportedFocusModes()
.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)
) {
// 自动对焦
params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)
}
params.setPreviewFormat(ImageFormat.NV21) // 设置预览图片格式
params.setPictureFormat(ImageFormat.JPEG) // 设置拍照图片格式
camera!!.setParameters(params)
try {
camera?.setPreviewCallback(previewCallback)
camera?.setPreviewDisplay(holder)
//旋转90度
camera?.setDisplayOrientation(90)
camera?.startPreview()
} catch (ex: Exception) {
ex.printStackTrace()
camera?.release()
camera = null
}
// }
}
//关闭摄像机
private fun stopCamera() {
camera?.setPreviewCallback(null)
camera?.stopPreview()
camera?.release()
camera = null
}
}
预览的activity
import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import android.widget.FrameLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.example.mytest.R
class MyCameraActivity : AppCompatActivity() {
lateinit var mSurfaceView: MySurfaceView
lateinit var mFrameLayout: FrameLayout
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_my_camera)
mFrameLayout = findViewById(R.id.m_frameL)
mSurfaceView = MySurfaceView(this)
mFrameLayout.addView(mSurfaceView)
}
override fun onResume() {
super.onResume()
}
override fun onDestroy() {
requestPermission()
}
fun requestPermission() {
val REQUEST_CODE = 1
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) !== PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, arrayOf<String>(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE),
REQUEST_CODE
)
}
}
}
activity_my_camera.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".camera.MyCameraActivity">
<FrameLayout
android:id="@+id/m_frameL"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
当然这里使用到了拍照了 ,需要在manifest中注册权限并动态申请。
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />