C# 如何在Xamaring表单中翻转ZXing使用的相机
作为我正在开发的应用程序的一部分,我希望能够在使用前置或后置摄像头之间进行切换,但从我的搜索和尝试来看,我无法使用前置摄像头使其正常工作 进行扫描的scanner视图是来自ZXing.Net.Mobile.Forms的一个称为zxigscannerview的视图,它在我的xaml中定义,与应该进行相机翻转的按钮一起C# 如何在Xamaring表单中翻转ZXing使用的相机,c#,xamarin,xamarin.forms,zxing,zxing.net,C#,Xamarin,Xamarin.forms,Zxing,Zxing.net,作为我正在开发的应用程序的一部分,我希望能够在使用前置或后置摄像头之间进行切换,但从我的搜索和尝试来看,我无法使用前置摄像头使其正常工作 进行扫描的scanner视图是来自ZXing.Net.Mobile.Forms的一个称为zxigscannerview的视图,它在我的xaml中定义,与应该进行相机翻转的按钮一起 ... ... ... 按钮可在下图右上角看到,而扫描仪视图仅在扫描打开时可见,而扫描不在图像上 单击按钮应在使用前后摄像头之间切换,并将前摄像头作为默认设置。但是,单击按钮似
...
...
...
按钮可在下图右上角看到,而扫描仪视图仅在扫描打开时可见,而扫描不在图像上
单击按钮应在使用前后摄像头之间切换,并将前摄像头作为默认设置。但是,单击按钮似乎什么也不做,只会写入我的日志。按钮单击事件的代码如下所示
。。。
已单击private void CameraFlipButton_(对象发送方,事件参数e)
{
Logging.Log(LogType.Information,“翻转相机…”);
Config.DefaultOptions.usefrontcomeraifavailable=!Config.DefaultOptions.usefrontcomeraifailable;
Config.CustomOptions.usefrontcomeraifavailable=!Config.CustomOptions.usefrontcomeraifailable;
如果(!ScanningToggle.IsToggled)返回;
Logging.Log(LogType.Information,“重新启动扫描…”);
ScanningToggle.IsToggled=false;
ScanningToggle.IsToggled=true;
}
上面代码中提到的选项在我的Config类中定义为so。名为CustomOptions中的其他值在我的Config类的Init方法中设置,但这些值与这个问题无关
公共类配置
{
...
public static MobileBarcodeScanningOptions CustomOptions=new MobileBarcodeScanningOptions(){UseFrontCameraIfAvailable=true};
public static MobileBarcodeScanningOptions DefaultOptions=new MobileBarcodeScanningOptions(){UseFrontCameraIfAvailable=true};
...
}
我的扫描仪将使用的选项始终在这两个选项之间选择,具体取决于设置中的一些用户输入
为了让它发挥作用,我也试着
如果我遗漏了一些您认为有帮助的内容,您可以自由提问或要求额外的代码。我认为当它开始使用Zxing扫描时,无法切换前后摄像头,因此必须事先选择和设置该选项
var options = new MobileBarcodeScanningOptions
{
AutoRotate = true,
UseNativeScanning = true,
TryHarder = true,
TryInverted = true,
UseFrontCameraIfAvailable = true
};
var scannedCode = await _scanner.Scan(options);
我设法想出了如何成功地翻转相机
- 为此,我首先从包含ZXingScannerView的堆栈中删除它
- 然后,我创建了一个ZXingScannerView的新实例,复制了旧实例的所有设置(布局定位、ZXingScannerView特定值等)
- 然后,我将ZXingScannerView重新添加到堆栈中,对UseFrontCameraIfAvailable属性的任何更改都将从此生效
公共类GenericFactory
{
//帮助设置器访问:https://stackoverflow.com/questions/3762456/how-to-check-if-property-setter-is-public
公共静态T CopyProperties(T newObject、T oldObject、bool ignoreDefaults=true,
bool skipSelectedProperties=true,参数字符串[]skippedProperties),其中T:class
{
var类型=类型(T);
var properties=type.GetProperties();
foreach(属性中的var属性)
{
if(ignoreDefaults&&property.GetValue(oldObject)=默认值)
继续;
if(skipSelectedProperties&&skippedProperties.Contains(property.Name))
继续;
如果(!property.CanWrite)
继续;
SetValue(newObject,property.GetValue(oldObject));
}
返回newObject;
}
}
private void重新创建Scannerview()
{
if(Config.DebugMode)Logging.Log(LogType.Debug,$”{nam1eof(RecreateScannerView)}方法调用);
ScannerStack.Children.Remove(ScannerView);
if(Config.DebugMode)
Logging.Log(LogType.Debug,
$“将现有的{nameof(zxigscannerview)}转换为新的{nameof(zxigscannerview)}”的属性;
ScannerView=GenericFactory.CopyProperties(新的ZXingScannerView(){IsScanning=false},ScannerView,
skippedProperties:new List(){nameof(ScannerView.IsScanning)}.ToArray();
ScannerView.OnScanResult+=ScannerView_OnScanResult;
ScannerStack.Children.Add(ScannerView);
}
private void EnableScan(MobileBarcodeCanningoptions imputedOptions=null)
{
如果(Config.DebugMode)Logging.Log(LogType.Debug,$”{nameof(EnableScan)}方法在名为=>{Thread.CurrentThread.Name}的线程中运行;
var chosenOptions=inputedoptions??(Config.UseCustomOptions?Config.CustomOptions:Config.DefaultOptions);
if(Config.DebugMode)
Logging.Log(LogType.Infor