zxing得到图像流

时间:2016-09-11 18:29:05

标签: c# uwp qr-code zxing

我想从QR library zxing for UWP获取视频流。

我打算将流复制到两个输出中。因此,底层流可以通过Gaussian Blur Filter传递,并且顶部的流将清晰地显示为屏幕中心的二次几何(没有失真,就像'剪切窗口')。这样可以产生用户正在扫描并聚焦在非模糊区域(屏幕中间)并且周围模糊的效果。

我打算使用Lumia SDK或新的Composition API进行模糊处理,这两者都应该在视频操作方面非常快。

我怎样才能做到这一点?对于QR扫描仪来说,这肯定是一个不错的眼睛,而不是在CPU / GPU上太沉重。

1 个答案:

答案 0 :(得分:1)

  

我想从QR库zxing获取UWP的视频流

根据ZXing.Mobile的源代码,没有现有的API可以从ZXing获取视频流,但我们可以自行实施。

让我们看看Zxing.mobile是如何做到的:

  1. MobileBarcodeScanner.Scan method中,它实际导航到ScanPage视图

    rootFrame.Navigate(typeof(ScanPage), new ScanPageNavigationParameters 
    {//......
    }
    
  2. ScanPage视图,ZXingScannerControl控件将用于承担主要任务:

    <zxing:ZXingScannerControl x:Name="scannerControl">
    
    </zxing:ZXingScannerControl>
    
  3. StartScanningAsync method中,原则是使用MediaCapture API来启动相机预览并调用GetPreviewFrameAsync方法来获取计时器中的预览帧,此帧可以转换为LuminanceSource,使用BarcodeReader.Decode方法解码此图片中的条形码。

    // Set the capture element's source to show it in the UI
        captureElement.Source = mediaCapture;
    
        // Start the preview
        await mediaCapture.StartPreviewAsync();
    

    ...

    SoftwareBitmapLuminanceSource luminanceSource = null;
    
            try
            {
                // Get preview 
                var frame = await mediaCapture.GetPreviewFrameAsync(videoFrame);
    
                // Create our luminance source
                luminanceSource = new SoftwareBitmapLuminanceSource(frame.SoftwareBitmap);
    

    ...

     ZXing.Result result = null;
    
            try
            {
                // Try decoding the image
                if (luminanceSource != null)
                    result = zxing.Decode(luminanceSource);
    
  4.   

    因此,底层流可以通过高斯模糊滤波器,顶部的流将清晰地显示为屏幕中心的二次几何(没有失真,就像一个&#39;切出窗口&#39 )。

    您可以先尝试MediaCapture.CapturePhotoToStreamAsynchere

    中有类似的讨论

    如果要在屏幕中心显示二次几何,可以放置一个Canvas来包含这些几何对象,请参阅官方Basic face tracking sample

    XAML:

     <CaptureElement Name="CamPreview" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stretch="Fill" Margin="0,10,0,0" />
     <Canvas Name="VisualizationCanvas" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0,10,0,0" />
    

    代码背后:

    private void SetupVisualization(Windows.Foundation.Size framePizelSize, IList<DetectedFace> foundFaces)
        {
                this.VisualizationCanvas.Children.Clear();
    
                double actualWidth = this.VisualizationCanvas.ActualWidth;
                double actualHeight = this.VisualizationCanvas.ActualHeight;
    
                if (this.currentState == ScenarioState.Streaming && foundFaces != null && actualWidth != 0 && actualHeight != 0)
                {
                    double widthScale = framePizelSize.Width / actualWidth;
                    double heightScale = framePizelSize.Height / actualHeight;
    
                    foreach (DetectedFace face in foundFaces)
                    {
                        // Create a rectangle element for displaying the face box but since we're using a Canvas
                        // we must scale the rectangles according to the frames's actual size.
                        Rectangle box = new Rectangle();
                        box.Width = (uint)(face.FaceBox.Width / widthScale);
                        box.Height = (uint)(face.FaceBox.Height / heightScale);
                        box.Fill = this.fillBrush;
                        box.Stroke = this.lineBrush;
                        box.StrokeThickness = this.lineThickness;
                        box.Margin = new Thickness((uint)(face.FaceBox.X / widthScale), (uint)(face.FaceBox.Y / heightScale), 0, 0);
    
                        this.VisualizationCanvas.Children.Add(box);
                    }
                }
            }