Skip to content

Commit

Permalink
fix: Fix ResolutionSelector.forSize not respecting aspect ratio (#3026
Browse files Browse the repository at this point in the history
)

* fix: Fix `ResolutionSelector.forSize` not respecting aspect ratio

* fix: Also use that selector now for Preview
  • Loading branch information
mrousavy authored Jun 26, 2024
1 parent f5b55dc commit 9ca6643
Show file tree
Hide file tree
Showing 6 changed files with 13 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,6 @@ data class CameraConfiguration(
data class Audio(val nothing: Unit)
data class Preview(val surfaceProvider: SurfaceProvider)

val targetPreviewAspectRatio: Float?
get() {
val format = format ?: return null
val video = video as? Output.Enabled<Video>
val photo = photo as? Output.Enabled<Photo>
return if (video != null) {
// Video capture is enabled, use video aspect ratio
format.videoWidth.toFloat() / format.videoHeight.toFloat()
} else if (photo != null) {
// Photo capture is enabled, use photo aspect ratio
format.photoWidth.toFloat() / format.photoHeight.toFloat()
} else {
null
}
}

@Suppress("EqualsOrHashCode")
sealed class Output<T> {
val isEnabled: Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,10 @@ internal fun CameraSession.configureOutputs(configuration: CameraConfiguration)
preview.setTargetFrameRate(fpsRange)
}

val targetPreviewAspectRatio = configuration.targetPreviewAspectRatio
if (targetPreviewAspectRatio != null) {
Log.i(CameraSession.TAG, "Preview aspect ratio: $targetPreviewAspectRatio")
if (format != null) {
// Similar to iOS, Preview will follow video size as it's size (and aspect ratio)
val previewResolutionSelector = ResolutionSelector.Builder()
.forAspectRatio(targetPreviewAspectRatio)
.forSize(format.videoSize)
.setAllowedResolutionMode(ResolutionSelector.PREFER_CAPTURE_RATE_OVER_HIGHER_RESOLUTION)
.build()
preview.setResolutionSelector(previewResolutionSelector)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@ import android.util.Size
import androidx.camera.core.resolutionselector.ResolutionSelector
import kotlin.math.abs

private fun difference(left: Size, right: Size): Int = abs(left.width * left.height - right.width * right.height)
private fun sizeDifference(left: Size, right: Size): Int = abs(left.width * left.height - right.width * right.height)
private fun aspectRatioDifference(left: Size, right: Size): Float = abs(left.aspectRatio - right.aspectRatio)

/**
* Gets a [ResolutionSelector] that finds a resolution closest to the given target size.
* There will always be a size available, but it is not guaranteed that it will be exactly the target size.
* It is also possible that the resolved size is larger than the target size.
* The given target size's aspect ratio will have priority over sizes with a similar number of total pixels.
*/
fun ResolutionSelector.Builder.forSize(size: Size): ResolutionSelector.Builder {
return this.setResolutionFilter { supportedSizes, _ ->
return@setResolutionFilter supportedSizes.sortedBy { difference(it, size) }
return@setResolutionFilter supportedSizes.sortedWith(compareBy({ aspectRatioDifference(it, size) }, { sizeDifference(it, size) }))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.mrousavy.camera.core.extensions

import android.util.Size

val Size.aspectRatio: Float
get() = width.toFloat() / height.toFloat()

This file was deleted.

0 comments on commit 9ca6643

Please sign in to comment.