C# 如何在Xamaring表单中翻转ZXing使用的相机

C# 如何在Xamaring表单中翻转ZXing使用的相机,c#,xamarin,xamarin.forms,zxing,zxing.net,C#,Xamarin,Xamarin.forms,Zxing,Zxing.net,作为我正在开发的应用程序的一部分,我希望能够在使用前置或后置摄像头之间进行切换,但从我的搜索和尝试来看,我无法使用前置摄像头使其正常工作 进行扫描的scanner视图是来自ZXing.Net.Mobile.Forms的一个称为zxigscannerview的视图,它在我的xaml中定义,与应该进行相机翻转的按钮一起 ... ... ... 按钮可在下图右上角看到,而扫描仪视图仅在扫描打开时可见,而扫描不在图像上 单击按钮应在使用前后摄像头之间切换,并将前摄像头作为默认设置。但是,单击按钮似

作为我正在开发的应用程序的一部分,我希望能够在使用前置或后置摄像头之间进行切换,但从我的搜索和尝试来看,我无法使用前置摄像头使其正常工作

进行扫描的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};
...
}
我的扫描仪将使用的选项始终在这两个选项之间选择,具体取决于设置中的一些用户输入

为了让它发挥作用,我也试着

  • 在扫描运行时反转UseFrontCameraIfAvailable值

  • 将用于启动扫描然后重新启动扫描的选项上的UseFrontCameraiFavable值反转为UseFrontCameraiFavable(如上所示代码)

  • 更改是将ZXingScannerView的扫描从true更改为false,同时使用更改的选项重新启动扫描,但这只会导致相机冻结

  • 在我即将提交问题时发现了此问题。明天我将尝试遵循这一点,但仍然非常希望我的输入


    如果我遗漏了一些您认为有帮助的内容,您可以自由提问或要求额外的代码。

    我认为当它开始使用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属性的任何更改都将从此生效

    它成功的代码如下。首先是复制属性的通用方法,然后是重新创建ZXingScannerView的方法,最后是启用扫描的我的方法

    公共类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