Xamarin Camera2Basic 示例在 UnlockFocus 调用后引发异常
Xamarin Camera2Basic sample throws exception after UnlockFocus call
已下载 Xamarin Camera2Basic 项目
最初在 Visual Studio 2017 模拟器中开始测试时一切正常。
注释掉"CameraCaptureStillPictureSessionCallback.cs"中的代码,如下图所示,以允许在单击"Take Picture"按钮后在模拟器屏幕上显示捕获的静止图像:
public override void OnCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result)
{
//Owner.ShowToast("Saved: " + Owner.mFile);
//Log.Debug(TAG, Owner.mFile.ToString());
//Owner.UnlockFocus();
}
单击 "Take Picture" 按钮会隐藏自身,并在屏幕上显示另一个标记为 "Retake Picture" 的按钮(这是我在事后添加的,代码位于 Camera2BasicFragment.cs 文件中,但代码与问题无关紧要)。
单击现在可见的 "Retake Picture" 按钮会执行以下操作:
- 隐藏自己
- 显示 "Take Picture" 按钮
- 调用 UnlockFocus()
UnlockFocus() 允许相机的流连续显示在屏幕上,而不是之前捕获的静止图像。
现在,当我再次单击 "Take Picture" 按钮(尝试捕捉新的静止图像)时,应用程序崩溃了。
Visual studio 不提供任何有意义的错误消息。最接近有用的信息是设备日志中显示的错误消息:
07-26 23:29:03.201 10.1" Marshmallow (6.0.0) XHDPI Tablet Error 6987 BufferQueueProducer [ImageReader-640x480f100m2-6987-0] dequeueBuffer: can't dequeue multiple buffers without setting the buffer count
07-26 23:29:07.174 10.1" Marshmallow (6.0.0) XHDPI Tablet Error 6987 RequestThread-0 Hit timeout for jpeg callback!
07-26 23:29:03.201 10.1" Marshmallow (6.0.0) XHDPI Tablet Error 6987 Legacy-CameraDevice-JNI LegacyCameraDevice_nativeProduceFrame: Error while producing frame Function not implemented (-38).
我不确定如何处理这些错误,或者要更改哪些 settings/code 以允许 "Retake Picture" 功能在不导致应用程序崩溃的情况下运行。
有什么建议吗?
编辑 1:
根据请求,我目前拥有的项目 link 在哪里。
https://drive.google.com/file/d/0B7OSuA_ybXcFb081T210UlQzZkE/view?usp=sharing
这里还有一些看似相关的信息:
此代码 运行 使用:
一个。 Windows 10 Pro,Visual Studio 2017 社区,Android 模拟器
对于 Visual Studio、Hyper-v 虚拟管理器、Android 6.0
(Marshamallow SDK 23),平板电脑大小的模板
b。 2013 Macbook Pro, Visual Studio For Mac (最新版), 默认
emaulator,Android 6.0 (Marshmallow SDK 23),平板电脑大小的模板。
在两种环境中都观察到在第二次 "LockFocus" 调用后拍摄快照失败。
Mac 更容易找到一些更有意义的错误:
一个。我看到的错误发生在方法 "produceFrame" 里面
LegacyCameraDevice.java
我也遇到了这个演示的问题,这背后的真正问题是关于 IOnImageAvailableListener,它不会触发 OnImageAvailable 方法来保存图片...
阅读代码后,我发现该演示已损坏,缺少一些部分。
在 Camera2BasicFragment.cs 中,在 OnCreateMethod 中,您需要添加此行
mCaptureCallback = new CameraCaptureListener() { Owner = this};
整个方法应该如下所示:
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
mStateCallback = new CameraStateListener() { owner = this };
mSurfaceTextureListener = new Camera2BasicSurfaceTextureListener(this);
// fill ORIENTATIONS list
ORIENTATIONS.Append((int)SurfaceOrientation.Rotation0, 90);
ORIENTATIONS.Append((int)SurfaceOrientation.Rotation90, 0);
ORIENTATIONS.Append((int)SurfaceOrientation.Rotation180, 270);
ORIENTATIONS.Append((int)SurfaceOrientation.Rotation270, 180);
}
有趣的是,如果你在模拟器上运行这个,什么也不会发生,因为在CameraCaptureListener.cs文件中,它总是return 0,而不是ControlAFState.FocusedLocked 或 ControlAFState.InActivate
Integer afState = (Integer)result.Get(CaptureResult.ControlAfState);
事件如果我破解 If 方法能够 运行 跳转到下一步,ImageAvailableListener.cs 的方法 OnImageAvaiable 将永远不会被模拟器触发。但是如果我 运行 在真实设备上,它 运行 可以吗?!
所以解决方法是:
1. 添加上面的代码,就像我在 onCreate 函数中解释的那样。
2. 不要使用模拟器运行 Camera2,它有问题。
希望对您有所帮助:)
如果您还有兴趣; IOnImageAvailableListener 不触发 OnImageAvailable 方法 in Visual Studio Emulator For Android.
代码正确,但 Visual Studio Android 的模拟器有错误。我希望他们尽快修复它。另一方面,您可以使用 Android Studio Emulator 在 Xamarin 中尝试您的代码,没有任何错误。 这很容易,您不需要了解任何有关 Java 的信息或 Android Studio 只需按照以下步骤操作
- 使用虚拟设备安装Android Studio
- 关闭电脑上的 Hper-v(windows -> 控制面板 -> 程序 -> 程序和功能 -> 打开或关闭 windows 功能)
- 打开 android 工作室 -> 工具 -> Avd 管理器 -> 创建虚拟设备
Visual studio 检测虚拟设备只需在 Visual Studio Xamarin
上使用它
希望对您有所帮助
已下载 Xamarin Camera2Basic 项目
最初在 Visual Studio 2017 模拟器中开始测试时一切正常。
注释掉"CameraCaptureStillPictureSessionCallback.cs"中的代码,如下图所示,以允许在单击"Take Picture"按钮后在模拟器屏幕上显示捕获的静止图像:
public override void OnCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result)
{
//Owner.ShowToast("Saved: " + Owner.mFile);
//Log.Debug(TAG, Owner.mFile.ToString());
//Owner.UnlockFocus();
}
单击 "Take Picture" 按钮会隐藏自身,并在屏幕上显示另一个标记为 "Retake Picture" 的按钮(这是我在事后添加的,代码位于 Camera2BasicFragment.cs 文件中,但代码与问题无关紧要)。
单击现在可见的 "Retake Picture" 按钮会执行以下操作:
- 隐藏自己
- 显示 "Take Picture" 按钮
- 调用 UnlockFocus()
UnlockFocus() 允许相机的流连续显示在屏幕上,而不是之前捕获的静止图像。
现在,当我再次单击 "Take Picture" 按钮(尝试捕捉新的静止图像)时,应用程序崩溃了。
Visual studio 不提供任何有意义的错误消息。最接近有用的信息是设备日志中显示的错误消息:
07-26 23:29:03.201 10.1" Marshmallow (6.0.0) XHDPI Tablet Error 6987 BufferQueueProducer [ImageReader-640x480f100m2-6987-0] dequeueBuffer: can't dequeue multiple buffers without setting the buffer count
07-26 23:29:07.174 10.1" Marshmallow (6.0.0) XHDPI Tablet Error 6987 RequestThread-0 Hit timeout for jpeg callback!
07-26 23:29:03.201 10.1" Marshmallow (6.0.0) XHDPI Tablet Error 6987 Legacy-CameraDevice-JNI LegacyCameraDevice_nativeProduceFrame: Error while producing frame Function not implemented (-38).
我不确定如何处理这些错误,或者要更改哪些 settings/code 以允许 "Retake Picture" 功能在不导致应用程序崩溃的情况下运行。
有什么建议吗?
编辑 1: 根据请求,我目前拥有的项目 link 在哪里。
https://drive.google.com/file/d/0B7OSuA_ybXcFb081T210UlQzZkE/view?usp=sharing
这里还有一些看似相关的信息:
此代码 运行 使用:
一个。 Windows 10 Pro,Visual Studio 2017 社区,Android 模拟器 对于 Visual Studio、Hyper-v 虚拟管理器、Android 6.0 (Marshamallow SDK 23),平板电脑大小的模板
b。 2013 Macbook Pro, Visual Studio For Mac (最新版), 默认 emaulator,Android 6.0 (Marshmallow SDK 23),平板电脑大小的模板。
在两种环境中都观察到在第二次 "LockFocus" 调用后拍摄快照失败。
Mac 更容易找到一些更有意义的错误:
一个。我看到的错误发生在方法 "produceFrame" 里面 LegacyCameraDevice.java
我也遇到了这个演示的问题,这背后的真正问题是关于 IOnImageAvailableListener,它不会触发 OnImageAvailable 方法来保存图片...
阅读代码后,我发现该演示已损坏,缺少一些部分。 在 Camera2BasicFragment.cs 中,在 OnCreateMethod 中,您需要添加此行
mCaptureCallback = new CameraCaptureListener() { Owner = this};
整个方法应该如下所示:
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
mStateCallback = new CameraStateListener() { owner = this };
mSurfaceTextureListener = new Camera2BasicSurfaceTextureListener(this);
// fill ORIENTATIONS list
ORIENTATIONS.Append((int)SurfaceOrientation.Rotation0, 90);
ORIENTATIONS.Append((int)SurfaceOrientation.Rotation90, 0);
ORIENTATIONS.Append((int)SurfaceOrientation.Rotation180, 270);
ORIENTATIONS.Append((int)SurfaceOrientation.Rotation270, 180);
}
有趣的是,如果你在模拟器上运行这个,什么也不会发生,因为在CameraCaptureListener.cs文件中,它总是return 0,而不是ControlAFState.FocusedLocked 或 ControlAFState.InActivate
Integer afState = (Integer)result.Get(CaptureResult.ControlAfState);
事件如果我破解 If 方法能够 运行 跳转到下一步,ImageAvailableListener.cs 的方法 OnImageAvaiable 将永远不会被模拟器触发。但是如果我 运行 在真实设备上,它 运行 可以吗?!
所以解决方法是: 1. 添加上面的代码,就像我在 onCreate 函数中解释的那样。 2. 不要使用模拟器运行 Camera2,它有问题。
希望对您有所帮助:)
如果您还有兴趣; IOnImageAvailableListener 不触发 OnImageAvailable 方法 in Visual Studio Emulator For Android.
代码正确,但 Visual Studio Android 的模拟器有错误。我希望他们尽快修复它。另一方面,您可以使用 Android Studio Emulator 在 Xamarin 中尝试您的代码,没有任何错误。 这很容易,您不需要了解任何有关 Java 的信息或 Android Studio 只需按照以下步骤操作
- 使用虚拟设备安装Android Studio
- 关闭电脑上的 Hper-v(windows -> 控制面板 -> 程序 -> 程序和功能 -> 打开或关闭 windows 功能)
- 打开 android 工作室 -> 工具 -> Avd 管理器 -> 创建虚拟设备
Visual studio 检测虚拟设备只需在 Visual Studio Xamarin
上使用它希望对您有所帮助