简体   繁体   English

使用UWP C#的Hololens条码读取器

[英]Hololens barcode reader using UWP C#

Here i would like to know about reading the barcode from hololens. 在这里,我想了解有关从Hololens读取条形码的信息。

public sealed partial class ScanQrPage : Page
{
    public bool SoftwareTriggerStarted { get; set; } = false;
    bool isSelectionChanging = false;
    public bool IsScannerClaimed { get; set; } = false;
    public bool ScannerSupportsPreview { get; set; } = false;
    ClaimedBarcodeScanner claimedScanner = null;
    static readonly Guid rotationGuid = new Guid("C380465D-2271-428C-9B83-ECEA3B4A85C1");
    BarcodeScanner selectedScanner = null;
    MediaCapture mediaCapture;
    DeviceWatcher watcher;
    ObservableCollection<BarcodeScannerInfo> barcodeScanners = new ObservableCollection<BarcodeScannerInfo>();
    DisplayRequest displayRequest = new DisplayRequest();
    public ScanQrPage()
    {
        this.InitializeComponent();
        watcher = DeviceInformation.CreateWatcher(BarcodeScanner.GetDeviceSelector());
        watcher.Added += Watcher_Added;
        watcher.Removed += Watcher_Removed;
        watcher.Updated += Watcher_Updated;
        watcher.Start();

    }
    private async void StartSoftwareTriggerButton_Click(object sender, RoutedEventArgs e)
    {
        Grd_btn.Visibility = Visibility.Collapsed;
        scanQr.Visibility = Visibility.Visible;
        if (claimedScanner != null)
        {
            await claimedScanner.StartSoftwareTriggerAsync();

            SoftwareTriggerStarted = true;
            RaisePropertyChanged(nameof(SoftwareTriggerStarted));
        }
    }
    private async void StopSoftwareTriggerButton_Click(object sender, RoutedEventArgs e)
    {
        Grd_btn.Visibility = Visibility.Visible;
        scanQr.Visibility = Visibility.Collapsed;
        if (claimedScanner != null)
        {
            await claimedScanner.StopSoftwareTriggerAsync();
            result.Text = "";
            SoftwareTriggerStarted = false;
            RaisePropertyChanged(nameof(SoftwareTriggerStarted));
        }
    }
    private async void Watcher_Added(DeviceWatcher sender, DeviceInformation args)
    {
        await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
        {
            barcodeScanners.Add(new BarcodeScannerInfo(args.Name, args.Id));
            await SelectScannerAsync(args.Id.ToString());
        });
    }
    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChanged(string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    private async void ClaimedScanner_DataReceived(ClaimedBarcodeScanner sender, BarcodeScannerDataReceivedEventArgs args)
    {
        await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
        {
            result.Text = DataHelpers.GetDataLabelString(args.Report.ScanDataLabel, args.Report.ScanDataType);
            var s2 = DataHelpers.GetDataString(args.Report.ScanData);
            var s3 = BarcodeSymbologies.GetName(args.Report.ScanDataType);
            var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
            localSettings.Values["UserName"] = DataHelpers.GetDataLabelString(args.Report.ScanDataLabel, args.Report.ScanDataType);

            if (result.Text.ToString() != "Result") {
                Helper.Alert(result.Text.ToString());
            }
                //Frame.Navigate(typeof(Dashboard));
            else
                Helper.Alert("Please Scan a QR/BarCode to Login");
        });
    }
    private async Task SelectScannerAsync(string scannerDeviceId)
    {
        selectedScanner = await BarcodeScanner.FromIdAsync(scannerDeviceId);

        if (selectedScanner != null)
        {
            claimedScanner = await selectedScanner.ClaimScannerAsync();
            if (claimedScanner != null)
            {
                await claimedScanner.EnableAsync();
                ScannerSupportsPreview = !String.IsNullOrEmpty(selectedScanner.VideoDeviceId);
                RaisePropertyChanged(nameof(ScannerSupportsPreview));
                claimedScanner.DataReceived += ClaimedScanner_DataReceived;
                if (ScannerSupportsPreview)
                    await StartMediaCaptureAsync(selectedScanner.VideoDeviceId);
            }
            else
            {
                //rootPage.NotifyUser("Failed to claim the selected barcode scanner", NotifyType.ErrorMessage);
            }

        }
        else
        {
            //rootPage.NotifyUser("Failed to create a barcode scanner object", NotifyType.ErrorMessage);
        }

        IsScannerClaimed = claimedScanner != null;
        RaisePropertyChanged(nameof(IsScannerClaimed));

        isSelectionChanging = false;
    }
    private void Watcher_Removed(DeviceWatcher sender, DeviceInformationUpdate args)
    {
        // We don't do anything here, but this event needs to be handled to enable realtime updates.
        // See https://aka.ms/devicewatcher_added.
    }

    private void Watcher_Updated(DeviceWatcher sender, DeviceInformationUpdate args)
    {
        // We don't do anything here, but this event needs to be handled to enable realtime updates.
        //See https://aka.ms/devicewatcher_added.
    }
    private async Task StartMediaCaptureAsync(string videoDeviceId)
    {
        mediaCapture = new MediaCapture();

        // Register for a notification when something goes wrong
        mediaCapture.Failed += MediaCapture_Failed;

        var settings = new MediaCaptureInitializationSettings
        {
            VideoDeviceId = videoDeviceId,
            StreamingCaptureMode = StreamingCaptureMode.Video,
            SharingMode = MediaCaptureSharingMode.SharedReadOnly,
        };

        // Initialize MediaCapture
        bool captureInitialized = false;
        try
        {
            await mediaCapture.InitializeAsync(settings);
            captureInitialized = true;
        }
        catch (UnauthorizedAccessException)
        {
            //rootPage.NotifyUser("The app was denied access to the camera", NotifyType.ErrorMessage);
        }
        catch (Exception e)
        {
            //rootPage.NotifyUser("Failed to initialize the camera: " + e.Message, NotifyType.ErrorMessage);
        }

        if (captureInitialized)
        {
            // Prevent the device from sleeping while the preview is running.
            displayRequest.RequestActive();

            PreviewControl.Source = mediaCapture;
            await mediaCapture.StartPreviewAsync();
            await SetPreviewRotationAsync(DisplayInformation.GetForCurrentView().CurrentOrientation);
            //IsPreviewing = true;
            //RaisePropertyChanged(nameof(IsPreviewing));
        }
        else
        {
            mediaCapture.Dispose();
            mediaCapture = null;
        }
    }
    private async Task SetPreviewRotationAsync(DisplayOrientations displayOrientation)
    {
        bool isExternalCamera;
        bool isPreviewMirrored;

        // Figure out where the camera is located to account for mirroring and later adjust rotation accordingly.
        DeviceInformation cameraInformation = await DeviceInformation.CreateFromIdAsync(selectedScanner.VideoDeviceId);

        if ((cameraInformation.EnclosureLocation == null) || (cameraInformation.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Unknown))
        {
            isExternalCamera = true;
            isPreviewMirrored = false;
        }
        else
        {
            isExternalCamera = false;
            isPreviewMirrored = (cameraInformation.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Front);
        }

        PreviewControl.FlowDirection = isPreviewMirrored ? FlowDirection.RightToLeft : FlowDirection.LeftToRight;

        if (!isExternalCamera)
        {
            // Calculate which way and how far to rotate the preview.
            int rotationDegrees = 0;
            switch (displayOrientation)
            {
                case DisplayOrientations.Portrait:
                    rotationDegrees = 90;
                    break;
                case DisplayOrientations.LandscapeFlipped:
                    rotationDegrees = 180;
                    break;
                case DisplayOrientations.PortraitFlipped:
                    rotationDegrees = 270;
                    break;
                case DisplayOrientations.Landscape:
                default:
                    rotationDegrees = 0;
                    break;
            }

            // The rotation direction needs to be inverted if the preview is being mirrored.
            if (isPreviewMirrored)
            {
                rotationDegrees = (360 - rotationDegrees) % 360;
            }

            // Add rotation metadata to the preview stream to make sure the aspect ratio / dimensions match when rendering and getting preview frames.
            var streamProperties = mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview);
            streamProperties.Properties[rotationGuid] = rotationDegrees;
            await mediaCapture.SetEncodingPropertiesAsync(MediaStreamType.VideoPreview, streamProperties, null);
        }
    }
    private void MediaCapture_Failed(MediaCapture sender, MediaCaptureFailedEventArgs errorEventArgs)
    {

    }

    private void Back_Tapped(object sender, TappedRoutedEventArgs e)
    {
        if (Frame.CanGoBack)
            Frame.GoBack();
    }

    private void ResultButton_Click(object sender, TappedRoutedEventArgs e)
    {
        if (result.Text != "Result")
        {
            Frame.Navigate(typeof(Dashboard));
        }
    }


}
public class BarcodeScannerInfo
{
    public BarcodeScannerInfo(String deviceName, String deviceId)
    {
        DeviceName = deviceName;
        DeviceId = deviceId;
    }

    public String Name => $"{DeviceName} ({DeviceId})";
    public String DeviceId { get; private set; }
    private string DeviceName;
}



public partial class DataHelpers
{
    public static string GetDataString(IBuffer data)
    {
        if (data == null)
        {
            return "No data";
        }

        // Just to show that we have the raw data, we'll print the value of the bytes.
        // Arbitrarily limit the number of bytes printed to 20 so the UI isn't overloaded.
        string result = CryptographicBuffer.EncodeToHexString(data);
        if (result.Length > 40)
        {
            result = result.Substring(0, 40) + "...";
        }
        return result;
    }

    public static string GetDataLabelString(IBuffer data, uint scanDataType)
    {
        // Only certain data types contain encoded text.
        // To keep this simple, we'll just decode a few of them.
        if (data == null)
        {
            return "No data";
        }

        // This is not an exhaustive list of symbologies that can be converted to a string.
        if (scanDataType == BarcodeSymbologies.Upca ||
            scanDataType == BarcodeSymbologies.UpcaAdd2 ||
            scanDataType == BarcodeSymbologies.UpcaAdd5 ||
            scanDataType == BarcodeSymbologies.Upce ||
            scanDataType == BarcodeSymbologies.UpceAdd2 ||
            scanDataType == BarcodeSymbologies.UpceAdd5 ||
            scanDataType == BarcodeSymbologies.Ean8 ||
            scanDataType == BarcodeSymbologies.TfStd ||
            scanDataType == BarcodeSymbologies.OcrA ||
            scanDataType == BarcodeSymbologies.OcrB)
        {
            // The UPC, EAN8, and 2 of 5 families encode the digits 0..9
            // which are then sent to the app in a UTF8 string (like "01234").
            return CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8, data);
        }

        // Some other symbologies (typically 2-D symbologies) contain binary data that
        // should not be converted to text.
        //return string.Format("Decoded data unavailable. Raw label data: {0}", DataHelpers.GetDataString(data));
        return CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8, data);
    }
}

This is my code that works fine in my Windows 10 PC. 这是我的代码,可以在Windows 10 PC上正常工作。

When i package the same code and deployed into Hololens, I can't able to read the Barcode/Qrcode. 当我打包相同的代码并部署到Hololens中时,我无法读取条形码/ Qrcode。

Is there any hardware specification that i need to enable or any other that i have missed here? 我需要启用任何硬件规格,还是在这里错过任何其他规格?

@Nandha, @Nandha,

The challenge with reading barcodes with HoloLens V1 is that the camera is only capable of fixed focus when streaming the image. 使用HoloLens V1读取条形码的挑战在于,相机仅在流式传输图像时才能够固定焦点。 It is unable to autofocus on the barcode and thus it is difficult to get the barcode into the exact focus for a successful read. 它无法自动聚焦在条形码上,因此很难将条形码准确地对准以成功读取。 It may work with a barcode that is sufficiently large, but I would not expect it to be reliable on standard sized barcodes. 它可以与足够大的条形码一起使用,但是我不希望它在标准尺寸的条形码上可靠。 Hopefully the camera in a future version of HoloLens will have the needed auto-focus functionality for barcode decoding. 希望HoloLens未来版本中的相机将具有条形码解码所需的自动对焦功能。

Terry Warwick, Microsoft 微软特里·沃威克

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM