首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Android CameraX API缩放相机?

如何使用Android CameraX API缩放相机?
EN

Stack Overflow用户
提问于 2019-05-09 10:23:33
回答 4查看 12.7K关注 0票数 8

我试着用下面的代码放大相机,使用CameraX

首先,我从Preview获得了一个CameraX,并尝试使用Preview进行缩放,如下所示。

代码语言:javascript
复制
var config = CameraX.getDefaultUseCaseConfig(PreviewConfig::class.java, lensFacing)
var preview = Preview(config)
preview.zoom(zoom)

preview.zoom()之后,我只需要再次绑定CameraX,得到一些错误,它就不能工作了。

代码语言:javascript
复制
CameraX.bindToLifecycle(this, preview, imageCapture, videoCapture)

当上面的代码不起作用时,我先尝试使用CameraX.unbindAll(),然后调用CameraX.bindToLifecycle()。但再次面对一些错误,无法在变焦方面取得成功。

CameraX 让我知道如何使用 API.放大摄像机。

更新错误日志如下:

仅使用CameraX.bindToLifecycle()**:** 错误日志

代码语言:javascript
复制
java.lang.IllegalArgumentException: Exceeded max simultaneously bound image capture use cases.
   at androidx.camera.camera2.impl.UseCaseSurfaceOccupancyManager.checkUseCaseLimitNotExceeded(UseCaseSurfaceOccupancyManager.java:61)
   at androidx.camera.camera2.impl.Camera2DeviceSurfaceManager.getSuggestedResolutions(Camera2DeviceSurfaceManager.java:146)
   at androidx.camera.core.CameraX.calculateSuggestedResolutions(CameraX.java:449)
   at androidx.camera.core.CameraX.bindToLifecycle(CameraX.java:144)
   at com.android.example.cameraxbasic.fragments.CameraFragment$updateCameraUi$2.onTouch(CameraFragment.kt:408)
   at android.view.View.dispatchTouchEvent(View.java:12512)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3032)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2719)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3032)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2719)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3032)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2719)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3032)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2719)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3032)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2719)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3032)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2719)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3032)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2719)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3032)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2719)
   at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:475)
   at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1836)
   at android.app.Activity.dispatchTouchEvent(Activity.java:3404)
   at androidx.appcompat.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
   at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:433)
   at android.view.View.dispatchPointerEvent(View.java:12755)
   at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:5150)
   at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4953)
   at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4470)
   at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4523)
   at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4489)
   at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4629)
   at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4497)
   at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4686)
   at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4470)
   at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4523)
   at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4489)
   at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4497)
   at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4470)
   at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:7192)
   at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:7126)
   at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:7087)
   at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:7295)
   at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:193)
   at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
   at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:184)
   at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:7266)
   at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:7318)
   at android.view.Choreographer$CallbackRecord.run(Choreographer.java:949)
   at android.view.Choreographer.doCallbacks(Choreographer.java:761)
   at android.view.Choreographer.doFrame(Choreographer.java:690)
   at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:935)
   at android.os.Handler.handleCallback(Handler.java:873)
   at android.os.Handler.dispatchMessage(Handler.java:99)
   at android.os.Looper.loop(Looper.java:193)
   at android.app.ActivityThread.main(ActivityThread.java:6912)
   at java.lang.reflect.Method.invoke(Native Method)
   at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:860)

使用CameraX.unbindAll() CameraX.bindToLifecycle()**:**的错误日志

代码语言:javascript
复制
   E/Legacy-CameraDevice-JNI: getNativeWindow: Surface had no valid native window.
   E/Legacy-CameraDevice-JNI: LegacyCameraDevice_nativeDetectSurfaceDimens: Could not retrieve native window from surface.

--------- beginning of crash
   2019-05-09 16:49:29.155 31123-31144/com.android.example.cameraxbasic E/AndroidRuntime: FATAL EXCEPTION: CameraX-
Process: com.android.example.cameraxbasic, PID: 31123
java.lang.IllegalArgumentException: Surface was abandoned
    at android.hardware.camera2.utils.SurfaceUtils.getSurfaceSize(SurfaceUtils.java:84)
    at android.hardware.camera2.params.OutputConfiguration.<init>(OutputConfiguration.java:260)
    at android.hardware.camera2.params.OutputConfiguration.<init>(OutputConfiguration.java:145)
    at android.hardware.camera2.impl.CameraDeviceImpl.createCaptureSession(CameraDeviceImpl.java:518)
    at androidx.camera.camera2.impl.CaptureSession.open(CaptureSession.java:196)
    at androidx.camera.camera2.impl.Camera.openCaptureSession(Camera.java:535)
    at androidx.camera.camera2.impl.Camera$StateCallback.onOpened(Camera.java:743)
    at androidx.camera.core.CameraDeviceStateCallbacks$ComboDeviceStateCallback.onOpened(CameraDeviceStateCallbacks.java:99)
    at android.hardware.camera2.impl.CameraDeviceImpl$1.run(CameraDeviceImpl.java:152)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:193)
    at android.os.HandlerThread.run(HandlerThread.java:65)
 Caused by: android.hardware.camera2.legacy.LegacyExceptionUtils$BufferQueueAbandonedException
    at android.hardware.camera2.legacy.LegacyExceptionUtils.throwOnError(LegacyExceptionUtils.java:73)
    at android.hardware.camera2.legacy.LegacyCameraDevice.getSurfaceSize(LegacyCameraDevice.java:606)
    at android.hardware.camera2.utils.SurfaceUtils.getSurfaceSize(SurfaceUtils.java:82)
    at android.hardware.camera2.params.OutputConfiguration.<init>(OutputConfiguration.java:260) 
    at android.hardware.camera2.params.OutputConfiguration.<init>(OutputConfiguration.java:145) 
    at android.hardware.camera2.impl.CameraDeviceImpl.createCaptureSession(CameraDeviceImpl.java:518) 
    at androidx.camera.camera2.impl.CaptureSession.open(CaptureSession.java:196) 
    at androidx.camera.camera2.impl.Camera.openCaptureSession(Camera.java:535) 
    at androidx.camera.camera2.impl.Camera$StateCallback.onOpened(Camera.java:743) 
    at androidx.camera.core.CameraDeviceStateCallbacks$ComboDeviceStateCallback.onOpened(CameraDeviceStateCallbacks.java:99) 
    at android.hardware.camera2.impl.CameraDeviceImpl$1.run(CameraDeviceImpl.java:152) 
    at android.os.Handler.handleCallback(Handler.java:873) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:193) 
    at android.os.HandlerThread.run(HandlerThread.java:65) 


--------- beginning of system
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2020-01-22 08:47:19

最后,我们得到了CameraX中的Zoom。请检查以下两种方式,您可以用来缩放相机的预览。

夹点放大:

代码语言:javascript
复制
val scaleGestureDetector = ScaleGestureDetector(context, listener)

cameraTextureView.setOnTouchListener { _, event ->
    scaleGestureDetector.onTouchEvent(event)
    return@setOnTouchListener true
}

val listener = object : ScaleGestureDetector.SimpleOnScaleGestureListener() {
    override fun onScale(detector: ScaleGestureDetector): Boolean {
        val scale = cameraInfo.zoomRatio.value * detector.scaleFactor
        cameraControl.setZoomRatio(scale)
        return true
    }
}

幻灯片缩放(使用查找栏):

代码语言:javascript
复制
zoomSeekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {        
    override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
        cameraControl.setLinearZoom(progress / 100.toFloat())
    }

    override fun onStartTrackingTouch(seekBar: SeekBar?) {}

    override fun onStopTrackingTouch(seekBar: SeekBar?) {}
})

使用下面的cameraControl**:**获取

代码语言:javascript
复制
val cameraControl = CameraX.getCameraControl(lensFacing)

代码参考链接: https://github.com/Pinkal7600/camera-samples/tree/master/CameraXBasic

票数 11
EN

Stack Overflow用户

发布于 2019-05-14 09:44:06

要使缩放正常工作,还需要在bindToLifecycle()之后调用缩放()。还请注意,缩放()接受位于传感器坐标中的Rect。有关更多详细信息,请参阅这里

您还可能需要使用camera2 API来获取传感器有源阵列和相机id (请使用具有正确LENS_FACING的第一个LENS_FACING)。我们知道这是很多工作,所以我们正在开发一个新的更高级别的缩放API,它更容易使用,也更简单。

票数 3
EN

Stack Overflow用户

发布于 2019-05-14 00:13:02

看起来这个错误与预览缩放:java.lang.IllegalArgumentException: Exceeded max simultaneously bound image capture use cases.无关

这表明您在解除绑定之前多次调用CameraX.bindToLifecycle(imageCapture),这就是导致崩溃的原因。我还建议使用配置生成器而不是getDefaultUseCaseConfig,因为它们更显着,更易于阅读,而getDefaultUseCaseConfig是一个隐藏的API。

有关更多细节,请参阅官方样品的示例实现和文档

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56057310

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档