在这里,我想了解有关从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的未来版本中的相机将具有条形码解码所需的自动对焦功能。
微软特里·沃威克