使用CameraX拍摄的图像不是设备相机产生的高分辨率输出大小



我试图通过cameraX实现获得高分辨率图像。通过下面的代码,我可以看到,对于设备的后置摄像头,我测试了一个分辨率为4000x3000的条目。

@RequiresApi(Build.VERSION_CODES.M)
fun getPossibleOutputSizes(id: String) {
val cameraManager = context?.getSystemService(Context.CAMERA_SERVICE) as CameraManager
val sizes = cameraManager?.getCameraCharacteristics(id)?.get(SCALER_STREAM_CONFIGURATION_MAP)?.getHighResolutionOutputSizes(ImageFormat.JPEG)
if (sizes != null) {
println("got possible resolutions:")
println(sizes.joinToString("n"))
}
}

以下是设置相机的代码。这是一个我用来检查camera X takePhoto调用提供的输出分辨率的示例应用程序。

/** Declare and bind preview, capture and analysis use cases */
@SuppressLint("RestrictedApi", "ServiceCast", "UnsafeOptInUsageError")
private fun bindCameraUseCases() {
// Get screen metrics used to setup camera for full screen resolution
val metrics = windowManager.getCurrentWindowMetrics().bounds
Log.d(TAG, "Screen metrics: ${metrics.width()} x ${metrics.height()}")
val screenAspectRatio = aspectRatio(metrics.width(), metrics.height())
Log.d(TAG, "Preview aspect ratio: $screenAspectRatio")
val rotation = fragmentCameraBinding.viewFinder.display.rotation
// CameraProvider
val cameraProvider = cameraProvider
?: throw IllegalStateException("Camera initialization failed.")
// CameraSelector
var cameraSelector = CameraSelector.Builder().requireLensFacing(lensFacing).build()
selectExternalOrBestCamera(cameraProvider)?.let { returnedCameraSelector ->
cameraSelector = returnedCameraSelector

}
// Preview
preview = Preview.Builder()
// We request aspect ratio but no resolution
.setTargetAspectRatio(screenAspectRatio)//either RATIO_4_3 or RATIO_16_9
// Set initial target rotation
.setTargetRotation(rotation)
.build()
// ImageCapture
imageCapture = ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_ZERO_SHUTTER_LAG)
// We request aspect ratio but no resolution to match preview config, but letting
// CameraX optimize for whatever specific resolution best fits our use cases
// Set initial target rotation, we will have to call this again if rotation changes
// during the lifecycle of this use case
//.setTargetAspectRatio(AspectRatio.RATIO_4_3)//tried both RATIO_4_3 and RATIO_16_9
.setTargetResolution(Size(3000, 4000))//tried 4000 * 3000 too..
.setTargetRotation(rotation)
//.setDefaultCaptureConfig(config)
.build()
// Must unbind the use-cases before rebinding them
cameraProvider.unbindAll()
try {
// A variable number of use-cases can be passed here -
// camera provides access to CameraControl & CameraInfo
camera = cameraProvider.bindToLifecycle(
this, cameraSelector, preview, imageCapture)
// Attach the viewfinder's surface provider to preview use case
preview?.setSurfaceProvider(fragmentCameraBinding.viewFinder.surfaceProvider)
observeCameraState(camera?.cameraInfo!!)
} catch (exc: Exception) {
Log.e(TAG, "Use case binding failed", exc)
}
}

我试图利用camera X中的可用配置,但无法获得与getPossibleOutputSizes中相同分辨率的高分辨率输出。我测试的所有设备似乎都是这样。但设备摄像头能够提供该分辨率的图像,基于摄像头2的实现也是如此。

这是camera X的限制还是我错过了什么?

不幸的是,截至2023年1月,使用getHighResolutionOutputSizes返回的高分辨率无法与CameraX一起使用。我不知道有什么变通办法。Bug报告和当前状态可在此处找到:https://issuetracker.google.com/issues/162121234目前的展望是,该功能应该与CameraX 1.3版本一起提供。

编辑20.04.23:昨天发布了1.3.0-alpha06版本,现在应该可以使用了:https://developer.android.com/jetpack/androidx/releases/camera#1.3.0-alpha06

最新更新