Ich denke, Sie haben Recht mit MediaCapture
und ZXing
Lib, aber ich denke, es sollte Kamera Vorschau Frame funktioniert. Meine Idee ist, die Kamera zu initialisieren, dann den Vorschau-Rahmen zu bekommen und ihn auf WriteableBitmap
zu drehen und zuletzt Zxing
Api zu verwenden, um dies WriteableBitmap
zu analysieren.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="4*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<CaptureElement x:Name="PreviewControl" Stretch="Uniform" Grid.Row="0" />
<Button Content="Click Me" Click="Button_Click" Grid.Row="1" />
<TextBlock x:Name="txtDecoderType" Grid.Row="2" />
<TextBlock x:Name="txtDecoderContent" Grid.Row="3" />
</Grid>
wichtiger Punkt in meinem Code hier:
Hier ist meine Probe
public MainPage()
{
this.InitializeComponent();
NavigationCacheMode = NavigationCacheMode.Required;
// Useful to know when to initialize/clean up the camera
Application.Current.Suspending += Application_Suspending;
Application.Current.Resuming += Application_Resuming;
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
_displayOrientation = _displayInformation.CurrentOrientation;
_displayInformation.OrientationChanged += DisplayInformation_OrientationChanged;
await InitializeCameraAsync();
await _mediaCapture.VideoDeviceController.FocusControl.FocusAsync();
await GetPreviewFrameAsSoftwareBitmapAsync();
}
private readonly DisplayInformation _displayInformation = DisplayInformation.GetForCurrentView();
private DisplayOrientations _displayOrientation = DisplayOrientations.Portrait;
// Rotation metadata to apply to the preview stream (MF_MT_VIDEO_ROTATION)
// Reference: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868174.aspx
private static readonly Guid RotationKey = new Guid("C380465D-2271-428C-9B83-ECEA3B4A85C1");
// Prevent the screen from sleeping while the camera is running
private readonly DisplayRequest _displayRequest = new DisplayRequest();
// For listening to media property changes
private readonly SystemMediaTransportControls _systemMediaControls = SystemMediaTransportControls.GetForCurrentView();
// MediaCapture and its state variables
private MediaCapture _mediaCapture;
private bool _isInitialized = false;
private bool _isPreviewing = false;
// Information about the camera device
private bool _mirroringPreview = false;
private bool _externalCamera = false;
private async void Application_Suspending(object sender, SuspendingEventArgs e)
{
// Handle global application events only if this page is active
// See official sample
}
private async void Application_Resuming(object sender, object o)
{
// Handle global application events only if this page is active
// See official sample
}
protected override async void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
// Handling of this event is included for completenes, as it will only fire when navigating between pages and this sample only includes one page
// See official sample
}
private async void SystemMediaControls_PropertyChanged(SystemMediaTransportControls sender, SystemMediaTransportControlsPropertyChangedEventArgs args)
{
// See official sample
}
private async void DisplayInformation_OrientationChanged(DisplayInformation sender, object args)
{
// See official sample
}
private async void MediaCapture_Failed(MediaCapture sender, MediaCaptureFailedEventArgs errorEventArgs)
{
// See official sample
}
private async Task InitializeCameraAsync()
{
Debug.WriteLine("InitializeCameraAsync");
if (_mediaCapture == null)
{
// Attempt to get the back camera if one is available, but use any camera device if not
var cameraDevice = await FindCameraDeviceByPanelAsync(Windows.Devices.Enumeration.Panel.Back);
if (cameraDevice == null)
{
Debug.WriteLine("No camera device found!");
return;
}
// Create MediaCapture and its settings
_mediaCapture = new MediaCapture();
// Register for a notification when something goes wrong
_mediaCapture.Failed += MediaCapture_Failed;
var settings = new MediaCaptureInitializationSettings { VideoDeviceId = cameraDevice.Id };
// Initialize MediaCapture
try
{
await _mediaCapture.InitializeAsync(settings);
_isInitialized = true;
}
catch (UnauthorizedAccessException)
{
Debug.WriteLine("The app was denied access to the camera");
}
// If initialization succeeded, start the preview
if (_isInitialized)
{
// Figure out where the camera is located
if (cameraDevice.EnclosureLocation == null || cameraDevice.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Unknown)
{
// No information on the location of the camera, assume it's an external camera, not integrated on the device
_externalCamera = true;
}
else
{
// Camera is fixed on the device
_externalCamera = false;
// Only mirror the preview if the camera is on the front panel
_mirroringPreview = (cameraDevice.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Front);
}
await StartPreviewAsync();
}
}
}
private async Task StartPreviewAsync()
{
Debug.WriteLine("StartPreviewAsync");
// Prevent the device from sleeping while the preview is running
_displayRequest.RequestActive();
// Register to listen for media property changes
_systemMediaControls.PropertyChanged += SystemMediaControls_PropertyChanged;
// Set the preview source in the UI and mirror it if necessary
PreviewControl.Source = _mediaCapture;
PreviewControl.FlowDirection = _mirroringPreview ? FlowDirection.RightToLeft : FlowDirection.LeftToRight;
// Start the preview
await _mediaCapture.StartPreviewAsync();
_isPreviewing = true;
// Initialize the preview to the current orientation
if (_isPreviewing)
{
await SetPreviewRotationAsync();
}
}
private async Task SetPreviewRotationAsync()
{
// Only need to update the orientation if the camera is mounted on the device
if (_externalCamera) return;
// Calculate which way and how far to rotate the preview
int rotationDegrees = ConvertDisplayOrientationToDegrees(_displayOrientation);
// The rotation direction needs to be inverted if the preview is being mirrored
if (_mirroringPreview)
{
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 props = _mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview);
props.Properties.Add(RotationKey, rotationDegrees);
await _mediaCapture.SetEncodingPropertiesAsync(MediaStreamType.VideoPreview, props, null);
}
private async Task StopPreviewAsync()
{
// See official sample
}
private async Task GetPreviewFrameAsSoftwareBitmapAsync()
{
// Get information about the preview
var previewProperties = _mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview) as VideoEncodingProperties;
// Create the video frame to request a SoftwareBitmap preview frame
var videoFrame = new VideoFrame(BitmapPixelFormat.Bgra8, (int)previewProperties.Width, (int)previewProperties.Height);
// Capture the preview frame
using (var currentFrame = await _mediaCapture.GetPreviewFrameAsync(videoFrame))
{
// Collect the resulting frame
SoftwareBitmap previewFrame = currentFrame.SoftwareBitmap;
WriteableBitmap wbmap = new WriteableBitmap((int)previewProperties.Width, (int)previewProperties.Height);
previewFrame.CopyToBuffer(wbmap.PixelBuffer);
qrcode(wbmap);
}
}
private async Task CleanupCameraAsync()
{
// See official sample
}
private static async Task<DeviceInformation> FindCameraDeviceByPanelAsync(Windows.Devices.Enumeration.Panel desiredPanel)
{
// See official sample
}
private static int ConvertDisplayOrientationToDegrees(DisplayOrientations orientation)
{
// See official sample
}
private async void qrcode(WriteableBitmap bmp)
{
IBarcodeReader reader = new BarcodeReader();
// detect and decode the barcode inside the bitmap
var result = reader.Decode(bmp);
// do something with the result
if (result != null)
{
txtDecoderType.Text = result.BarcodeFormat.ToString();
txtDecoderContent.Text = result.Text;
}
else
{
await GetPreviewFrameAsSoftwareBitmapAsync();
}
}
Ich habe diesen Code mit Lumia 950 getestet, es funktioniert schnell und fein manchmal an meiner Seite, aber manchmal kann es den Vorschaurahmen gerade nicht decodieren. Es ist also nur eine einfache Probe hier, nicht 100% korrekt kann in einem formellen Projekt verwendet werden. Was ich getan habe, ist zu versuchen Zxing
api mit dem offiziellen Camera preview frame sample zu verwenden, also, wenn Sie irgendwelche Probleme haben, um Vorschaubild zu bekommen, können Sie in dieses Beispiel schauen. Es gibt auch eine Zxing sample for QR code hier, Sie können sie auch herunterladen und überprüfen.
Ergänzung: Sie müssen die Funktionen Internet(Client)
, Microphone
, Webcam
in der Manifestdatei aktivieren.
Können Sie dekodiert fertig schlagen Sie einen Weg vor, um Video-Frame auf Windows Phone 8.1 Store-Apps zu behandeln? ohne 'CapturePhotoToStorageFileAsync' oder' CapturePhotoToStreamAsync' Methoden. –
@AndriiKrupka, ich bin mir nicht sicher, hier ist offiziell [Video Stabilisierung Beispiel] (https://github.com/Microsoft/Windows-Universal-samples/tree/master/Samples/CameraVideoStabilization), gibt es auch Vorschau-Frame, also denke ich, es ist dasselbe. Aber Sie wollen nicht 'CapturePhotoToStreamAsync' Methoden verwenden, also glaube ich nicht, dass es um Video oder Foto geht. Ich benutze' IBarcodeReader' von Zxing um 'WriteableBitmap' zu decodieren,' WriteableBitmap' ist hier notwendig. Aber ich bin nicht durch die ganze Bibliothek gegangen, vielleicht gibt es andere Methoden, um das Vorschauvideo direkt zu dekodieren? Kannst du das Zxing-Sample auf GitHub in meiner Antwort überprüfen? –
Ich habe gefunden, was ich wollte. http://stackoverflow.com/questions/28435818/implement-realtime-barcode-scanner-on-windows-phone-8-1-runtime-using-zxing-and –