如何在 Xamaring Forms 中翻转 ZXing 使用的 Camera [英] How to flip Camera used by ZXing in Xamaring Forms

查看:23
本文介绍了如何在 Xamaring Forms 中翻转 ZXing 使用的 Camera的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

As part of the app i'm developing i want the ability to change between using the front or back camera, but from my searches and attempts i haven't been able to get it to work using the front camera.

执行扫描的扫描仪视图是来自 ZXing.Net.Mobile.Forms 的名为 ZXingScannerView 的视图,在我的 xaml 中像这样定义,连同应该翻转相机的按钮.

The scanner view doing the scanning is the one from ZXing.Net.Mobile.Forms called ZXingScannerView, defined in my xaml like so, together with the button that should do the flipping of the camera.

<elements:AdvancedTabbedPage
...
xmlns:elements="clr-namespace:Wolf.Utility.Main.Xamarin.Elements;assembly=Wolf.Utility.Main"
xmlns:forms="clr-namespace:ZXing.Net.Mobile.Forms;assembly=ZXing.Net.Mobile.Forms">
...

<ContentPage>
   <ContentPage.ToolbarItems>
       <ToolbarItem Text="{x:Static resources:AppResources.CameraFlipText}" x:Name="CameraFlipButton" Clicked="CameraFlipButton_OnClicked"/>
   </ContentPage.ToolbarItems>
   <ContentPage.Content>
...
       <forms:ZXingScannerView x:Name="ScannerView" HeightRequest="200" IsAnalyzing="False" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" IsVisible="False" IsScanning="True"/>
...
   </ContentPage.Content>
</ContentPage>

可以在下图的右上角看到按钮,而扫描仪视图仅在扫描开启时可见,它不在图像上.

The Button can be seen in the top right of the following image, while the Scanner View is only visible while scanning is On, which it is not on the image.

发生扫描的页面的图像

单击该按钮应在使用前置和后置摄像头之间切换,前置摄像头为默认设置.但是,单击按钮似乎没有做任何事情,然后写入我的日志.按钮的 Clicked 事件代码如下所示.

Clicking the button should toggle between using the front and back camera, with the front one as the default. Clicking the button however, doesn't seem to do anything, other then write to my Log. Code for the Clicked event of the button can be seen below.

...
private void CameraFlipButton_OnClicked(object sender, EventArgs e)
        {
            Logging.Log(LogType.Information, "Flipping Camera...");

            Config.DefaultOptions.UseFrontCameraIfAvailable = !Config.DefaultOptions.UseFrontCameraIfAvailable;
            Config.CustomOptions.UseFrontCameraIfAvailable = !Config.CustomOptions.UseFrontCameraIfAvailable;

            if (!ScanningToggle.IsToggled) return;

            Logging.Log(LogType.Information, "Restarting Scanning...");
            ScanningToggle.IsToggled = false;
            ScanningToggle.IsToggled = true;
        }

上面代码中提到的选项是这样定义的,在我的 Config 类中.在我的 Config 类的 Init 方法中设置了名为 CustomOptions 的附加值,但这些与此问题无关.

The options mentioned in the above code is defined as so, in my Config class. Additional values in the one called CustomOptions are set in my Init method of my Config class, but those are irrelevant to this question.

public class Config
{
...
public static MobileBarcodeScanningOptions CustomOptions = new MobileBarcodeScanningOptions() { UseFrontCameraIfAvailable = true };
public static MobileBarcodeScanningOptions DefaultOptions = new MobileBarcodeScanningOptions() { UseFrontCameraIfAvailable = true };
...
}

我的扫描仪将使用的选项始终在这两个选项之间进行选择,具体取决于设置中的一些用户输入.

The options that my scanner will use, is always picked between these two, depending on a few user inputs in the settings.

尝试让它工作,我也尝试过......

Attempting to get it to work i have also tried to...

  1. 在扫描运行时反转 UseFrontCameraIfAvailable 值

  1. Invert the value UseFrontCameraIfAvailable, while scanning is running

反转用于开始扫描然后重新开始扫描的选项上的 UseFrontCameraIfAvailable 值 - 上面显示的代码.

Invert the value UseFrontCameraIfAvailable on the options used to start the scan with and then restarting the scan - The code shown above.

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

Change IsScanning of the ZXingScannerView from true to false, while restarting the scanning with changed options, but this just resulted in the camera freezing.

发现这个一个 因为我正要提交问题.明天我将尝试关注那个,但仍然非常喜欢我的意见.

Found this one as i was about to submit the question. I'm going to attempt to follow that one tomorrow, but would still very much like input on mine.

如果我遗漏了一些您认为可能会有所帮助的内容,请随时提出问题或要求提供额外的代码.

Fell free to ask questions, or ask for additional code if i have left something out, that you think could help.

推荐答案

我设法弄清楚如何成功翻转相机.

I managed to figure out how to successfully flip the camera.

  • 为此,我首先从包含它的堆栈中删除 ZXingScannerView.

  • To do so i first remove the ZXingScannerView from my stack that contains it.

然后我创建一个 ZXingScannerView 的新实例,复制旧实例的所有设置(布局定位、ZXingScannerView 特定值等).

Then i create a new instance of the ZXingScannerView, copying over all the settings from the old one (layout positioning, ZXingScannerView specific values and so on).

然后我将 ZXingScannerView 重新添加到堆栈中,从那里对 UseFrontCameraIfAvailable 属性的任何更改都生效了.

Then i re-add the ZXingScannerView to the stack, and from there any changes to the UseFrontCameraIfAvailable property took effect.

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

The code it made to succeed, is as follows. First the generic method that copies over properties, then the method that recreates the ZXingScannerView, and lastly my method that enables the scanning.

public class GenericFactory
    {
        // Assistance with Setter Accessibility: https://stackoverflow.com/questions/3762456/how-to-check-if-property-setter-is-public
        public static T CopyProperties<T>(T newObject, T oldObject, bool ignoreDefaults = true,
            bool skipSelectedProperties = true, params string[] skippedProperties) where T : class
        {
            var type = typeof(T);
            var properties = type.GetProperties();

            foreach (var property in properties)
            {
                if (ignoreDefaults && property.GetValue(oldObject) == default)
                    continue;
                if (skipSelectedProperties && skippedProperties.Contains(property.Name))
                    continue;
                if (!property.CanWrite)
                    continue;

                property.SetValue(newObject, property.GetValue(oldObject));
            }

            return newObject;
        }
    }

private void RecreateScannerView()
        {
            if (Config.DebugMode) Logging.Log(LogType.Debug, $"{nam1eof(RecreateScannerView)} method called");
            ScannerStack.Children.Remove(ScannerView);

            if (Config.DebugMode)
                Logging.Log(LogType.Debug,
                    $"Coping properties from existing {nameof(ZXingScannerView)} into a new {nameof(ZXingScannerView)}");
            ScannerView = GenericFactory.CopyProperties(new ZXingScannerView() {IsScanning = false}, ScannerView,
                skippedProperties: new List<string>() {nameof(ScannerView.IsScanning)}.ToArray());
            ScannerView.OnScanResult += ScannerView_OnScanResult;

            ScannerStack.Children.Add(ScannerView);
        }

private void EnableScan(MobileBarcodeScanningOptions imputedOptions = null)
        {
            if (Config.DebugMode) Logging.Log(LogType.Debug, $"{nameof(EnableScan)} Method is run in Thread named => {Thread.CurrentThread.Name}");

            var chosenOptions = imputedOptions ?? (Config.UseCustomOptions ? Config.CustomOptions : Config.DefaultOptions);
            if (Config.DebugMode)
                Logging.Log(LogType.Information,
                    $"Chose this option for Scanning => {(imputedOptions != null ? nameof(imputedOptions) : (Config.UseCustomOptions ? nameof(Config.CustomOptions) : nameof(Config.DefaultOptions)))}");
            ScannerView.Options = chosenOptions;

            RecreateScannerView();

            Logging.Log(LogType.Information, $"Starting the Scanning...");
            ScannerView.IsScanning = true;
            ScannerView.IsAnalyzing = true;
            ScannerView.IsVisible = true;

            if (Config.DebugMode)
                Logging.Log(LogType.Debug,
                    $"{nameof(EnableScan)} Called and Finished; ScannerView.IsAnalyzing => {ScannerView.IsAnalyzing}; ScannerView.IsVisible => {ScannerView.IsVisible}");
        }

我翻转 UseFrontCameraIfAvailable 值的方法是上面问题中显示的方法.

My method to flip the value of UseFrontCameraIfAvailable is the one shown in the question above.

希望这最终能帮助可能遇到类似问题的其他人.

Hope to this ends up helping others who might stumble upon a likewise issue.

这篇关于如何在 Xamaring Forms 中翻转 ZXing 使用的 Camera的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆