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

@@ -1,34 +1,9 @@
package com.mrousavy.camera.extensions
import android.content.res.Resources
import android.hardware.camera2.CameraCharacteristics
import android.media.CamcorderProfile
import android.os.Build
import android.util.Log
import android.util.Size
import android.view.SurfaceHolder
import android.view.SurfaceView
private fun getMaximumPreviewSize(): Size {
// See https://developer.android.com/reference/android/hardware/camera2/params/StreamConfigurationMap
// According to the Android Developer documentation, PREVIEW streams can have a resolution
// of up to the phone's display's resolution, with a maximum of 1920x1080.
val display1080p = Size(1920, 1080)
val displaySize = Size(Resources.getSystem().displayMetrics.widthPixels, Resources.getSystem().displayMetrics.heightPixels)
val isHighResScreen = displaySize.bigger >= display1080p.bigger || displaySize.smaller >= display1080p.smaller
Log.i("PreviewSize", "Phone has a ${displaySize.width} x ${displaySize.height} screen.")
return if (isHighResScreen) display1080p else displaySize
}
/**
* Gets the maximum Preview Resolution this device is capable of streaming at. (For [SurfaceView])
*/
fun CameraCharacteristics.getPreviewSize(): Size {
val config = this.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)!!
val previewSize = getMaximumPreviewSize()
val outputSizes = config.getOutputSizes(SurfaceHolder::class.java).sortedByDescending { it.width * it.height }
return outputSizes.first { it.bigger <= previewSize.bigger && it.smaller <= previewSize.smaller }
}
private fun getMaximumVideoSize(cameraId: String): Size? {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {

View File

@@ -0,0 +1,47 @@
package com.mrousavy.camera.extensions
import android.content.res.Resources
import android.hardware.camera2.CameraCharacteristics
import android.util.Log
import android.util.Size
import android.view.SurfaceHolder
import kotlin.math.abs
private fun getMaximumPreviewSize(): Size {
// See https://developer.android.com/reference/android/hardware/camera2/params/StreamConfigurationMap
// According to the Android Developer documentation, PREVIEW streams can have a resolution
// of up to the phone's display's resolution, with a maximum of 1920x1080.
val display1080p = Size(1920, 1080)
val displaySize = Size(Resources.getSystem().displayMetrics.widthPixels,
Resources.getSystem().displayMetrics.heightPixels)
val isHighResScreen = displaySize.bigger >= display1080p.bigger || displaySize.smaller >= display1080p.smaller
return if (isHighResScreen) display1080p else displaySize
}
fun CameraCharacteristics.getPreviewSizeFromAspectRatio(aspectRatio: Double): Size {
val config = this.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)!!
val maximumPreviewSize = getMaximumPreviewSize()
val outputSizes = config.getOutputSizes(SurfaceHolder::class.java)
.sortedByDescending { it.width * it.height }
.sortedBy { abs(aspectRatio - (it.bigger.toDouble() / it.smaller)) }
return outputSizes.first { it.bigger <= maximumPreviewSize.bigger && it.smaller <= maximumPreviewSize.smaller }
}
fun CameraCharacteristics.getAutomaticPreviewSize(): Size {
val config = this.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)!!
val maximumPreviewSize = getMaximumPreviewSize()
val outputSizes = config.getOutputSizes(SurfaceHolder::class.java)
.sortedByDescending { it.width * it.height }
return outputSizes.first { it.bigger <= maximumPreviewSize.bigger && it.smaller <= maximumPreviewSize.smaller }
}
fun CameraCharacteristics.getPreviewTargetSize(aspectRatio: Double?): Size {
return if (aspectRatio != null) {
getPreviewSizeFromAspectRatio(aspectRatio)
} else {
getAutomaticPreviewSize()
}
}