求助:在UWP中为摄像头实时视频添加Lumia 3.0 SDK晕影(Vignette)特效
给UWP摄像头实时视频添加Lumia Imaging SDK晕影(Vignette)特效
刚接触UWP的话,把官方C#示例转VB确实容易踩一些语法和异步处理的坑,我给你整理了一个简化版的C#实现,再补上VB转换的关键要点,这样你能快速给摄像头实时视频加上Lumia SDK的晕影特效~
第一步:准备工作
- 先给UWP项目安装Lumia Imaging SDK:在NuGet包管理器里搜索
Lumia.Imaging,安装适配UWP的最新版本 - 在
Package.appxmanifest里开启网络摄像头权限,不然没法访问设备摄像头
第二步:C#简化实现示例
XAML布局代码
<Page x:Class="VideoVignetteDemo.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <!-- 显示摄像头预览的控件 --> <CaptureElement x:Name="CaptureElement" Stretch="Uniform"/> <!-- 滑块用来实时调节晕影强度 --> <Slider x:Name="VignetteSlider" Minimum="0" Maximum="1" Value="0.5" VerticalAlignment="Bottom" Margin="20" ValueChanged="VignetteSlider_ValueChanged"/> </Grid> </Page>
C#后台核心代码
using System; using System.Collections.Generic; using Windows.Media.Capture; using Windows.Media.Effects; using Windows.UI.Xaml.Controls; using Lumia.Imaging; using Lumia.Imaging.Adjustments; namespace VideoVignetteDemo { public sealed partial class MainPage : Page { private MediaCapture _mediaCapture; private VignetteEffect _vignetteEffect; private VideoEffectDefinition _videoEffect; public MainPage() { this.InitializeComponent(); InitializeCameraAndEffectAsync(); } private async void InitializeCameraAndEffectAsync() { // 初始化摄像头捕获对象 _mediaCapture = new MediaCapture(); await _mediaCapture.InitializeAsync(); CaptureElement.Source = _mediaCapture; await _mediaCapture.StartPreviewAsync(); // 创建晕影特效实例 _vignetteEffect = new VignetteEffect { Intensity = 0.5, // 初始强度,范围0-1 Center = new Point(0.5, 0.5) // 晕影中心默认在画面中间 }; // 创建Lumia特效对应的视频特效定义 _videoEffect = new VideoEffectDefinition(typeof(LumiaVideoEffect).FullName); _videoEffect.Properties.Add("ImageProvider", _vignetteEffect); // 将特效添加到摄像头预览流 await _mediaCapture.AddVideoEffectAsync(_videoEffect, MediaStreamType.VideoPreview); } // 滑块实时修改晕影强度 private void VignetteSlider_ValueChanged(object sender, Windows.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e) { _vignetteEffect?.Intensity = e.NewValue; } // 自定义视频特效类,对接Lumia SDK和UWP视频流 public sealed class LumiaVideoEffect : IBasicVideoEffect { private IImageProvider _imageProvider; public void SetProperties(IPropertySet configuration) { if (configuration.TryGetValue("ImageProvider", out object value)) { _imageProvider = value as IImageProvider; } } public void ProcessFrame(ProcessVideoFrameContext context) { if (_imageProvider == null) return; // 把UWP视频帧转换成Lumia可处理的Bitmap,应用特效后输出 using var inputBitmap = new Bitmap(context.InputFrame.SoftwareBitmap); using var outputBitmap = new Bitmap(context.OutputFrame.SoftwareBitmap); _imageProvider.Source = inputBitmap; _imageProvider.RenderAsync(outputBitmap).AsTask().Wait(); } public void Close(MediaEffectClosedReason reason) => _imageProvider = null; public void DiscardQueuedFrames() { } public bool IsReadOnly => false; public IReadOnlyList<VideoEncodingProperties> SupportedEncodingProperties => new List<VideoEncodingProperties>(); public MediaMemoryTypes SupportedMemoryTypes => MediaMemoryTypes.Cpu; public void SetEncodingProperties(VideoEncodingProperties encodingProperties) { } } } }
第三步:VB.NET转换要点
如果要转成VB,重点注意这几个容易出错的地方:
- 异步方法要用
Async Sub/Async Function,调用时加Await - 接口成员要完整实现,尤其是泛型集合(比如
IReadOnlyList)的写法 - VB的
Using块对应C#的using语句,用来释放资源 - 类型转换和
TryGetValue的语法差异
VB核心代码片段
Imports Windows.Media.Capture Imports Windows.Media.Effects Imports Windows.UI.Xaml.Controls Imports Lumia.Imaging Imports Lumia.Imaging.Adjustments Imports System.Collections.Generic Public NotInheritable Class MainPage Inherits Page Private _mediaCapture As MediaCapture Private _vignetteEffect As VignetteEffect Private _videoEffect As VideoEffectDefinition Public Sub New() Me.InitializeComponent() InitializeCameraAndEffectAsync() End Sub Private Async Sub InitializeCameraAndEffectAsync() _mediaCapture = New MediaCapture() Await _mediaCapture.InitializeAsync() CaptureElement.Source = _mediaCapture Await _mediaCapture.StartPreviewAsync() _vignetteEffect = New VignetteEffect() With { .Intensity = 0.5, .Center = New Point(0.5, 0.5) } _videoEffect = New VideoEffectDefinition(GetType(LumiaVideoEffect).FullName) _videoEffect.Properties.Add("ImageProvider", _vignetteEffect) Await _mediaCapture.AddVideoEffectAsync(_videoEffect, MediaStreamType.VideoPreview) End Sub Private Sub VignetteSlider_ValueChanged(sender As Object, e As Windows.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs) If _vignetteEffect IsNot Nothing Then _vignetteEffect.Intensity = e.NewValue End If End Sub Public NotInheritable Class LumiaVideoEffect Implements IBasicVideoEffect Private _imageProvider As IImageProvider Public Sub SetProperties(configuration As IPropertySet) Implements IBasicVideoEffect.SetProperties Dim value As Object = Nothing If configuration.TryGetValue("ImageProvider", value) Then _imageProvider = TryCast(value, IImageProvider) End If End Sub Public Sub ProcessFrame(context As ProcessVideoFrameContext) Implements IBasicVideoEffect.ProcessFrame If _imageProvider Is Nothing Then Return Using inputBitmap As New Bitmap(context.InputFrame.SoftwareBitmap) Using outputBitmap As New Bitmap(context.OutputFrame.SoftwareBitmap) _imageProvider.Source = inputBitmap _imageProvider.RenderAsync(outputBitmap).AsTask().Wait() End Using End Using End Sub Public Sub Close(reason As MediaEffectClosedReason) Implements IBasicVideoEffect.Close _imageProvider = Nothing End Sub Public Sub DiscardQueuedFrames() Implements IBasicVideoEffect.DiscardQueuedFrames End Sub Public ReadOnly Property IsReadOnly As Boolean Implements IBasicVideoEffect.IsReadOnly Get Return False End Get End Property Public ReadOnly Property SupportedEncodingProperties As IReadOnlyList(Of VideoEncodingProperties) Implements IBasicVideoEffect.SupportedEncodingProperties Get Return New List(Of VideoEncodingProperties)() End Get End Property Public ReadOnly Property SupportedMemoryTypes As MediaMemoryTypes Implements IBasicVideoEffect.SupportedMemoryTypes Get Return MediaMemoryTypes.Cpu End Get End Property Public Sub SetEncodingProperties(encodingProperties As VideoEncodingProperties) Implements IBasicVideoEffect.SetEncodingProperties End Sub End Class End Class
注意事项
- 测试时尽量用带摄像头的真实设备,部分模拟器可能不支持摄像头预览
- 如果遇到权限问题,检查
Package.appxmanifest是否勾选了网络摄像头权限,Windows 10+可能需要动态请求权限 - 晕影的
Center属性可以自定义,比如New Point(0.2, 0.3)可以把晕影中心移到画面左上方
内容的提问来源于stack exchange,提问作者henrikl2000
相关产品推荐
相关产品推荐

