fix: Fix Preview stretching on Android (#2377)

* fix: Fix Preview stretching on Android

* fix: Simplify Preview size computation

* fix: Catch `stopRepeating` error

* fix: Fix preview size calculation

* Format code

* Update CameraSession.kt

* Enable CodeScanner in example app

* fix: Also update size on surface change

* Format

* fix: Flip sizes

* Revert that stuff again

* Update PreviewView.kt

* fix: Swap width and height in SurfaceHolder::setFixedSize
This commit is contained in:
Marc Rousavy
2024-01-11 16:33:40 +01:00
committed by GitHub
parent 2b10622559
commit 322b6fcbd6
6 changed files with 20 additions and 48 deletions

View File

@@ -4,13 +4,12 @@ import android.content.res.Resources
import android.hardware.camera2.CameraCharacteristics
import android.util.Size
import android.view.SurfaceHolder
import kotlin.math.abs
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 display1080p = Size(1080, 1920)
val displaySize = Size(
Resources.getSystem().displayMetrics.widthPixels,
Resources.getSystem().displayMetrics.heightPixels
@@ -20,28 +19,11 @@ fun getMaximumPreviewSize(): Size {
return if (isHighResScreen) display1080p else displaySize
}
fun CameraCharacteristics.getPreviewSizeFromAspectRatio(aspectRatio: Double): Size {
fun CameraCharacteristics.getPreviewTargetSize(targetSize: Size?): 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)) }
.filter { it.bigger <= maximumPreviewSize.bigger && it.smaller <= maximumPreviewSize.smaller }
return outputSizes.first { it.bigger <= maximumPreviewSize.bigger && it.smaller <= maximumPreviewSize.smaller }
return outputSizes.closestToOrMax(targetSize)
}
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 =
if (aspectRatio != null) {
getPreviewSizeFromAspectRatio(aspectRatio)
} else {
getAutomaticPreviewSize()
}

View File

@@ -9,7 +9,7 @@ import kotlin.math.min
fun List<Size>.closestToOrMax(size: Size?): Size =
if (size != null) {
this.minBy { abs(it.width - size.width) + abs(it.height - size.height) }
this.minBy { abs((it.width * it.height) - (size.width * size.height)) }
} else {
this.maxBy { it.width * it.height }
}