【发布时间】:2019-10-25 13:52:49
【问题描述】:
这里我想知道如何从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 电脑上运行良好。
当我打包相同的代码并部署到 Hololens 中时,我无法 读取条形码/二维码。
是否有任何我需要启用的硬件规范或我在这里错过的任何其他规范?
【问题讨论】:
-
功能下的
webcam是否启用?您是否正在使用同时访问相机的东西(例如 Vuforia)? -
是的,功能已启用。不,我不会将相机用于任何其他过程。
-
我不熟悉这个东西……也许它与剪辑有关?您的二维码应该在多远的距离内被识别?可能是摄像头上
Mixed Reality Camera Manager的Near Clip设置得太高了,这就是摄像头无法识别密码的原因? -
我正在尝试做同样的事情,如果我运行“BarcodeScanner.CheckHealth”,我会在 Hololens 中收到“无解码器”消息,对于 Windows,我遵循了这个:docs.microsoft.com/et-ee/windows/uwp/devices-sensors/… - 但是不知道如何在 Hololens 中这样做
标签: c# uwp qr-code barcode hololens