【问题标题】:SurfaceView how to Re-Create if it has been destroyedSurfaceView如果已被销毁如何重新创建
【发布时间】:2017-10-17 11:50:05
【问题描述】:

我通过 SurfaceView 创建了一个相机,但是当我按下 home 并再次返回活动时。 SurfaceView 不再显示任何内容。它没有调用 surfaceCreated(SurfaceHolder holder)

当我回到活动时。我该怎么办?

这是我用 Kotlin 编写的代码

class MyCameraView : SurfaceView , 
SurfaceHolder.Callback,Camera.PreviewCallback,Camera.FaceDetectionListener {

    private lateinit var mCamera : Camera
    var sizes : List<Camera.Size>? = null

    constructor( ctx : Context,  attrs : AttributeSet?) : super(ctx,attrs){
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        holder.addCallback(this)
    }

    constructor(ctx : Context):this(ctx,null){}

    override fun surfaceChanged(p0: SurfaceHolder?, format: Int, width: Int, height: Int) {
        Log.e("MyCameraView","CHANGE ")
        val sizes = mCamera.parameters.supportedPreviewSizes

        val size = getOptimalSzie(sizes)

        val supportWith = size.height
        val supportHeight : Int = size.width
        val radio : Float  = width.toFloat()/supportWith
        setMeasuredDimension(width,(supportHeight*radio).toInt())
        layout(0, (-(supportHeight*radio)/5).toInt(),width, ((supportHeight*radio).toInt()-(supportHeight*radio)/5).toInt())


    }

    override fun surfaceDestroyed(p0: SurfaceHolder?) {
        Log.e("MyCameraView","DESTORY")
        holder.removeCallback(this)
        mCamera.setPreviewCallback(null)
        mCamera.stopFaceDetection()
        mCamera.stopPreview()
        mCamera.lock()
        mCamera.release()
    }

    override fun surfaceCreated(p0: SurfaceHolder?) {

        Log.e("MyCameraView","OPEN")

        mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT)
        mCamera.setDisplayOrientation(90)
        mCamera.setPreviewCallback(this)
        mCamera.setPreviewDisplay(holder)

        mCamera.setFaceDetectionListener(this)
        mCamera.startPreview();
        mCamera.startFaceDetection()
    }

    private fun getOptimalSzie(sizes: List<Camera.Size>): Camera.Size {
        var pos = 0
        var ratio = 0
        var viewRatio = height/width
        sizes.forEachIndexed { index, size ->
            val curRatio = size.width/size.height
            if(ratio == 0 ) ratio = curRatio
            else if( (viewRatio - curRatio) < (viewRatio - ratio)  ){
                ratio = curRatio
                pos = index
            }
        }
        return sizes[pos]
    }

    override fun onPreviewFrame(data: ByteArray?, camera: Camera) {
        if(allowTake) {

            val parameters = camera.getParameters()
            val width = parameters.previewSize.width
            val height = parameters.previewSize.height

            val yuv = YuvImage(data, parameters.previewFormat, width, height, null)

            val out = ByteArrayOutputStream()
            yuv.compressToJpeg(Rect(0, 0, width, height), 50, out)
            val bytes = out.toByteArray()
            val b = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
            detected?.invoke(bytes)
            allowTake = false
            hasTake = true
        }
    }

    var hasTake = false
    private var allowTake = false
    override fun onFaceDetection(faces: Array<out Camera.Face>?, camera: Camera?) {
        if(!hasTake) {
            allowTake = true
        }
    }

    private var detected: ((bitmap : ByteArray) -> Unit)? = null

    fun onFaceDetected(detected : ( bitmap : ByteArray )->Unit){
        this.detected = detected
    }

}

【问题讨论】:

    标签: android android-camera surfaceview


    【解决方案1】:

    我喜欢它!我改为使用 TextureView。它有四个回调方法。这是其中之一

    onSurfaceTextureAvailable(surface: SurfaceTexture?, width: Int, height: Int)

    它是在我回到活动时调用的!!! 这样我再回来的时候就可以打开相机了

    【讨论】:

      猜你喜欢
      • 2015-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-23
      • 2016-06-14
      • 2016-05-20
      相关资源
      最近更新 更多