在这里,我想了解有关从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);
    }
}



  这是我的代码,可以在Windows 10 PC上正常工作。
  
  当我打包相同的代码并部署到Hololens中时,我无法
  读取条形码/二维码。


我需要启用任何硬件规格,还是在这里错过任何其他规格?

最佳答案

@Nandha,

使用HoloLens V1读取条形码的挑战在于,相机仅在流式传输图像时才能够固定焦点。它无法自动聚焦在条形码上,因此很难将条形码准确地对准以成功读取。它可以与足够大的条形码一起使用,但是我不希望它在标准尺寸的条形码上可靠。希望HoloLens的未来版本中的相机将具有条形码解码所需的自动对焦功能。

微软特里·沃威克

10-06 13:19