@@ -36,6 +36,11 @@ import androidx.camera.core.Preview
3636import androidx.camera.core.UseCase
3737import androidx.camera.core.UseCaseGroup
3838import androidx.camera.core.ViewPort
39+ import androidx.camera.core.resolutionselector.ResolutionSelector
40+ import androidx.camera.core.resolutionselector.ResolutionSelector.PREFER_CAPTURE_RATE_OVER_HIGHER_RESOLUTION
41+ import androidx.camera.core.resolutionselector.ResolutionSelector.PREFER_HIGHER_RESOLUTION_OVER_CAPTURE_RATE
42+ import androidx.camera.core.resolutionselector.ResolutionStrategy
43+ import androidx.camera.core.resolutionselector.ResolutionStrategy.FALLBACK_RULE_CLOSEST_LOWER_THEN_HIGHER
3944import androidx.camera.lifecycle.ProcessCameraProvider
4045import androidx.camera.video.FallbackStrategy
4146import androidx.camera.video.FileDescriptorOutputOptions
@@ -86,6 +91,7 @@ import org.fossify.commons.activities.BaseSimpleActivity
8691import org.fossify.commons.extensions.toast
8792import org.fossify.commons.helpers.PERMISSION_ACCESS_FINE_LOCATION
8893import org.fossify.commons.helpers.ensureBackgroundThread
94+ import kotlin.math.abs
8995
9096class CameraXPreview (
9197 private val activity : BaseSimpleActivity ,
@@ -222,10 +228,10 @@ class CameraXPreview(
222228 val isFullSize = resolution.isFullScreen
223229 previewView.scaleType = if (isFullSize) ScaleType .FILL_CENTER else ScaleType .FIT_CENTER
224230 val rotation = previewView.display.rotation
225- val rotatedResolution = getRotatedResolution (resolution, rotation )
231+ val targetResolution = Size (resolution.width, resolution.height )
226232
227- val previewUseCase = buildPreview(rotatedResolution , rotation)
228- val captureUseCase = getCaptureUseCase(rotatedResolution , rotation)
233+ val previewUseCase = buildPreview(targetResolution , rotation)
234+ val captureUseCase = getCaptureUseCase(targetResolution , rotation)
229235
230236 cameraProvider.unbindAll()
231237 camera = if (isFullSize) {
@@ -258,18 +264,10 @@ class CameraXPreview(
258264 setFlashlightState(config.flashlightState)
259265 }
260266
261- private fun getRotatedResolution (resolution : MySize , rotationDegrees : Int ): Size {
262- return if (rotationDegrees == Surface .ROTATION_0 || rotationDegrees == Surface .ROTATION_180 ) {
263- Size (resolution.height, resolution.width)
264- } else {
265- Size (resolution.width, resolution.height)
266- }
267- }
268-
269267 private fun buildPreview (resolution : Size , rotation : Int ): Preview {
270268 return Preview .Builder ()
271269 .setTargetRotation(rotation)
272- .setTargetResolution( resolution)
270+ .setResolutionSelector(getResolutionSelector( resolution) )
273271 .build().apply {
274272 setSurfaceProvider(previewView.surfaceProvider)
275273 }
@@ -295,7 +293,7 @@ class CameraXPreview(
295293 .setFlashMode(flashMode)
296294 .setJpegQuality(config.photoQuality)
297295 .setTargetRotation(rotation)
298- .setTargetResolution( resolution)
296+ .setResolutionSelector(getResolutionSelector( resolution) )
299297 .build()
300298 }
301299
@@ -306,6 +304,26 @@ class CameraXPreview(
306304 }
307305 }
308306
307+ private fun getResolutionSelector (resolution : Size ): ResolutionSelector {
308+ return ResolutionSelector .Builder ()
309+ .setResolutionStrategy(ResolutionStrategy (resolution, FALLBACK_RULE_CLOSEST_LOWER_THEN_HIGHER ))
310+ .setResolutionFilter { supportedSizes, rotationDegrees ->
311+ // Sort by closest image ratio
312+ supportedSizes.sortedBy {
313+ size -> abs(size.width / size.height.toFloat() - resolution.width / resolution.height.toFloat())
314+ }
315+ }
316+ .setAllowedResolutionMode(getAllowedResolutionMode())
317+ .build()
318+ }
319+
320+ private fun getAllowedResolutionMode (): Int {
321+ return when (config.captureMode) {
322+ CaptureMode .MINIMIZE_LATENCY -> PREFER_CAPTURE_RATE_OVER_HIGHER_RESOLUTION
323+ CaptureMode .MAXIMIZE_QUALITY -> PREFER_HIGHER_RESOLUTION_OVER_CAPTURE_RATE
324+ }
325+ }
326+
309327 private fun buildVideoCapture (): VideoCapture <Recorder > {
310328 val qualitySelector = QualitySelector .from(
311329 videoQualityManager.getUserSelectedQuality(cameraSelector).toCameraXQuality(),
0 commit comments