feat: Respect format's aspect ratio in Preview and add resizeMode prop (#1817)

* feat(preview): respect format's aspect ratio

* fix: code guidelines and previewSize in PreviewView

* feat: add resizeMode 'cover' and 'contain' on Android
This commit is contained in:
Maxime
2023-09-22 17:32:34 +02:00
committed by GitHub
parent 9add0eb571
commit c0b80b342b
8 changed files with 166 additions and 67 deletions

View File

@@ -7,9 +7,9 @@ import android.content.pm.PackageManager
import android.hardware.camera2.CameraManager
import android.util.Log
import android.util.Size
import android.view.Gravity
import android.view.ScaleGestureDetector
import android.view.Surface
import android.view.View
import android.widget.FrameLayout
import androidx.core.content.ContextCompat
import com.facebook.react.bridge.ReadableMap
@@ -23,6 +23,10 @@ import com.mrousavy.camera.parsers.Orientation
import com.mrousavy.camera.parsers.PixelFormat
import com.mrousavy.camera.parsers.Torch
import com.mrousavy.camera.parsers.VideoStabilizationMode
import com.mrousavy.camera.extensions.bigger
import com.mrousavy.camera.extensions.getPreviewTargetSize
import com.mrousavy.camera.extensions.smaller
import com.mrousavy.camera.parsers.ResizeMode
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -41,7 +45,7 @@ class CameraView(context: Context) : FrameLayout(context) {
companion object {
const val TAG = "CameraView"
private val propsThatRequirePreviewReconfiguration = arrayListOf("cameraId")
private val propsThatRequirePreviewReconfiguration = arrayListOf("cameraId", "format", "resizeMode")
private val propsThatRequireSessionReconfiguration =
arrayListOf("cameraId", "format", "photo", "video", "enableFrameProcessor", "pixelFormat")
private val propsThatRequireFormatReconfiguration = arrayListOf("fps", "hdr", "videoStabilizationMode", "lowLightBoost")
@@ -63,6 +67,7 @@ class CameraView(context: Context) : FrameLayout(context) {
// props that require format reconfiguring
var format: ReadableMap? = null
var resizeMode: ResizeMode = ResizeMode.COVER
var fps: Int? = null
var videoStabilizationMode: VideoStabilizationMode? = null
var hdr: Boolean? = null // nullable bool
@@ -81,7 +86,7 @@ class CameraView(context: Context) : FrameLayout(context) {
// session
internal val cameraSession: CameraSession
private var previewView: View? = null
private var previewView: PreviewView? = null
private var previewSurface: Surface? = null
internal var frameProcessor: FrameProcessor? = null
@@ -115,16 +120,30 @@ class CameraView(context: Context) : FrameLayout(context) {
updateLifecycle()
}
private fun getPreviewTargetSize(): Size {
val cameraId = cameraId ?: throw NoCameraDeviceError()
val format = format
val targetPreviewSize = if (format != null) Size(format.getInt("videoWidth"), format.getInt("videoHeight")) else null
val formatAspectRatio = if (targetPreviewSize != null) targetPreviewSize.bigger.toDouble() / targetPreviewSize.smaller else null
return this.cameraManager.getCameraCharacteristics(cameraId).getPreviewTargetSize(formatAspectRatio)
}
private fun setupPreviewView() {
removeView(previewView)
this.previewSurface = null
val cameraId = cameraId ?: return
val previewView = PreviewView(context, cameraManager, cameraId) { surface ->
if (cameraId == null) return
val previewView = PreviewView(context, this.getPreviewTargetSize(), resizeMode) { surface ->
previewSurface = surface
configureSession()
}
previewView.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
previewView.layoutParams = LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT,
Gravity.CENTER)
addView(previewView)
this.previewView = previewView
}
@@ -183,7 +202,7 @@ class CameraView(context: Context) : FrameLayout(context) {
// TODO: Allow previewSurface to be null/none
val previewSurface = previewSurface ?: return
val previewOutput = CameraOutputs.PreviewOutput(previewSurface)
val previewOutput = CameraOutputs.PreviewOutput(previewSurface, previewView?.targetSize)
val photoOutput = if (photo == true) {
CameraOutputs.PhotoOutput(targetPhotoSize)
} else {