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:
@@ -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()
|
||||
}
|
||||
|
@@ -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 }
|
||||
}
|
||||
|
Reference in New Issue
Block a user