我想从QR library zxing for UWP获取视频流。
我打算将流复制到两个输出中。因此,底层流可以通过Gaussian Blur Filter
传递,并且顶部的流将清晰地显示为屏幕中心的二次几何(没有失真,就像'剪切窗口')。这样可以产生用户正在扫描并聚焦在非模糊区域(屏幕中间)并且周围模糊的效果。
我打算使用Lumia SDK
或新的Composition API
进行模糊处理,这两者都应该在视频操作方面非常快。
我怎样才能做到这一点?对于QR扫描仪来说,这肯定是一个不错的眼睛,而不是在CPU / GPU上太沉重。
答案 0 :(得分:1)
我想从QR库zxing获取UWP的视频流
根据ZXing.Mobile
的源代码,没有现有的API可以从ZXing
获取视频流,但我们可以自行实施。
让我们看看Zxing.mobile是如何做到的:
在MobileBarcodeScanner.Scan
method中,它实际导航到ScanPage
视图
rootFrame.Navigate(typeof(ScanPage), new ScanPageNavigationParameters
{//......
}
ScanPage
视图,ZXingScannerControl
控件将用于承担主要任务:
<zxing:ZXingScannerControl x:Name="scannerControl">
</zxing:ZXingScannerControl>
在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);
因此,底层流可以通过高斯模糊滤波器,顶部的流将清晰地显示为屏幕中心的二次几何(没有失真,就像一个&#39;切出窗口&#39 )。
您可以先尝试MediaCapture.CapturePhotoToStreamAsync
,here
如果要在屏幕中心显示二次几何,可以放置一个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);
}
}
}