2016-04-26 22 views

回答

0

所以,我的解决办法

  1. 创建新的WinRT项目 “的Windows运行时组件(环球视窗)

  2. 在WinRT中创建

class CaptureVideoEffect : IBasicVideoEffect (from Windows.Media.Effects) 
  • 将效果附加到MediaCapture
  • await capture.AddEffectAsync(MediaStreamType.VideoPreview, typeof(CaptureVideoEffect).FullName, ...); 
    
  • 现在CaptureVideoEffect.ProcessFrame(ProcessVideoFrameContext上下文)你获得实时视频输出

  • 在CaptureVideoEffect。ProcessFrame跳过帧,如果先前没有成功解码

  • 获取的图像作为字节[]

  • var frameSize = inputFrameBitmap.PixelWidth * inputFrameBitmap.PixelHeight * 4; 
    var frameBuffer = new Windows.Storage.Streams.Buffer((uint)frameSize); 
    inputFrameBitmap.CopyToBuffer(frameBuffer); 
    byte[] bitmap = frameBuffer.ToArray(); 
    
  • 解码与
  • result = barcodeReader.Decode(bitmap, inputFrameBitmap.PixelWidth, inputFrameBitmap.PixelHeight, BitmapFormat.RGB32); 
    
    public sealed class BarcodeReader 
    { 
        public Result Decode([ReadOnlyArray] byte[] rawRGB, int width, int height, BitmapFormat format); 
    } 
    
    1

    我认为你是正确的使用MediaCaptureZXing lib,但我认为它应该工作相机预览框架。我的想法是初始化相机,然后获取预览帧并将其转为WriteableBitmap,最后使用Zxing Api分析此WriteableBitmap

    这里是我的示例:在我的代码在这里

    <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> 
    

    关键点:

    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(); 
        } 
    } 
    

    我测试过此代码的Lumia 950,它在我的身边,有时作品快速和精细,但有时它只是无法解码预览帧。所以这只是简单的例子,在正式项目中不能100%正确。我所做的是试图使用Zxing api与官方Camera preview frame sample,所以如果你有任何关于获取预览框架的问题,你可以看看这个例子。这里也有一个Zxing sample for QR code,你也可以下载它并进行检查。

    此外:您将需要启用清单文件中的Internet(Client),Microphone,Webcam功能。

    +0

    你能建议一些方法来处理Windows Phone 8.1商店应用程序的视频帧?没有'CapturePhotoToStorageFileAsync'或'CapturePhotoToStreamAsync'方法。 –

    +1

    @AndriiKrupka,我不确定,这里是官方的[视频稳定示例](https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/CameraVideoStabilization),还有预览框架,所以我认为它是一样的。但你不想使用'CapturePhotoToStreamAsync'方法,所以我不认为它是关于视频或照片的,我只是使用Zxing的'IBarcodeReader'来解码'WriteableBitmap','WriteableBitmap'在这里是必要的。但是我没有经过整个库,也许有其他方法直接解码预览视频?你可以在我的回答中查看GitHub上的Zxing示例吗? –

    +0

    我找到了我想要的东西。 http://stackoverflow.com/questions/28435818/implement-realtime-barcode-scanner-on-windows-phone-8-1-runtime-using-zxing-and –