You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:在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,重点注意这几个容易出错的地方:

  1. 异步方法要用Async Sub/Async Function,调用时加Await
  2. 接口成员要完整实现,尤其是泛型集合(比如IReadOnlyList)的写法
  3. VB的Using块对应C#的using语句,用来释放资源
  4. 类型转换和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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:04:03