Effetti video personalizzatiCustom video effects

L'articolo descrive come creare un componente Windows Runtime che implementa l'interfaccia IBasicVideoEffect per creare effetti personalizzati per flussi video.This article describes how to create a Windows Runtime component that implements the IBasicVideoEffect interface to create custom effects for video streams. Gli effetti personalizzati possono essere usati con varie API Windows Runtime diverse, tra cui MediaCapture, che consente l'accesso alla fotocamera di un dispositivo, e MediaComposition, che consente di creare composizioni complesse da clip multimediali.Custom effects can be used with several different Windows Runtime APIs including MediaCapture, which provides access to a device's camera, and MediaComposition, which allows you to create complex compositions out of media clips.

Aggiungere un effetto personalizzato all'appAdd a custom effect to your app

Un effetto video personalizzato è definito in una classe che implementa l'interfaccia IBasicVideoEffect .A custom video effect is defined in a class that implements the IBasicVideoEffect interface. Questa classe non può essere inclusa direttamente nel progetto dell'app.This class can't be included directly in your app's project. Devi invece usare un componente Windows Runtime per ospitare la classe dell'effetto video.Instead, you must use a Windows Runtime component to host your video effect class.

Aggiungere un componente Windows Runtime per l'effetto videoAdd a Windows Runtime component for your video effect

  1. In Microsoft Visual Studio, con la soluzione aperta, vai al menu File e scegli Aggiungi >Nuovo progetto.In Microsoft Visual Studio, with your solution open, go to the File menu and select Add->New Project.
  2. Seleziona il tipo di progetto Componente Windows Runtime (Windows universale).Select the Windows Runtime Component (Universal Windows) project type.
  3. Per questo esempio, assegna il nome VideoEffectComponent al progetto.For this example, name the project VideoEffectComponent. Faremo riferimento a questo nome nel codice in seguito.This name will be referenced in code later.
  4. Fare clic su OK.Click OK.
  5. Il modello di progetto crea una classe denominata Class1.cs.The project template creates a class called Class1.cs. In Esplora soluzioni fai clic con il pulsante destro del mouse sull'icona per Class1.cs e scegli Rinomina.In Solution Explorer, right-click the icon for Class1.cs and select Rename.
  6. Rinomina il file in ExampleVideoEffect.cs.Rename the file to ExampleVideoEffect.cs. Visual Studio visualizzerà un prompt per richiedere se vuoi aggiornare tutti i riferimenti con il nuovo nome.Visual Studio will show a prompt asking if you want to update all references to the new name. Fare clic su .Click Yes.
  7. Apri ExampleVideoEffect.cs e aggiorna la definizione della classe per implementare l'interfaccia IBasicVideoEffect.Open ExampleVideoEffect.cs and update the class definition to implement the IBasicVideoEffect interface.
public sealed class ExampleVideoEffect : IBasicVideoEffect

Devi includere gli spazi dei nomi seguenti nel file di classe dell'effetto per accedere a tutti i tipi usati negli esempi in questo articolo.You need to include the following namespaces in your effect class file in order to access all of the types used in the examples in this article.

using Windows.Media.Effects;
using Windows.Media.MediaProperties;
using Windows.Foundation.Collections;
using Windows.Graphics.DirectX.Direct3D11;
using Windows.Graphics.Imaging;

Implementare l'interfaccia IBasicVideoEffect tramite elaborazione softwareImplement the IBasicVideoEffect interface using software processing

L'effetto video deve implementare tutti i metodi e le proprietà dell'interfaccia IBasicVideoEffect .Your video effect must implement all of the methods and properties of the IBasicVideoEffect interface. Questa sezione descrive una semplice implementazione dell'interfaccia che usa l'elaborazione software.This section walks you through a simple implementation of this interface that uses software processing.

Metodo CloseClose method

Il sistema chiamerà il metodo Close sulla classe quando è necessario arrestare l'effetto.The system will call the Close method on your class when the effect should shut down. Dovresti usare questo metodo per eliminare qualsiasi risorsa creata.You should use this method to dispose of any resources you have created. L'argomento del metodo è un MediaEffectClosedReason che consente di sapere se l'effetto è stato chiuso normalmente, se si è verificato un errore o se l'effetto non supporta il formato di codifica necessario.The argument to the method is a MediaEffectClosedReason that lets you know whether the effect was closed normally, if an error occurred, or if the effect does not support the required encoding format.

public void Close(MediaEffectClosedReason reason)
{
    // Dispose of effect resources
}

Metodo DiscardQueuedFramesDiscardQueuedFrames method

Il metodo DiscardQueuedFrames viene chiamato quando è necessario reimpostare l'effetto.The DiscardQueuedFrames method is called when your effect should reset. Uno scenario tipico è quando l'effetto archivia i fotogrammi elaborati in precedenza per usarli nell'elaborazione del fotogramma corrente.A typical scenario for this is if your effect stores previously processed frames to use in processing the current frame. Quando viene chiamato questo metodo, devi eliminare il set di fotogrammi precedenti che hai salvato.When this method is called, you should dispose of the set of previous frames you saved. Questo metodo può essere usato per reimpostare qualsiasi stato relativo ai fotogrammi precedenti e non solo per i fotogrammi video accumulati.This method can be used to reset any state related to previous frames, not only accumulated video frames.

private int frameCount;
public void DiscardQueuedFrames()
{
    frameCount = 0;
}

proprietà IsReadOnlyIsReadOnly property

La proprietà IsReadOnly consente al sistema di verificare se l'effetto scriverà nell'output dell'effetto.The IsReadOnly property lets the system know if your effect will write to the output of the effect. Se l'app non modifica i fotogrammi video, come nel caso di un effetto che esegue solo l'analisi dei fotogrammi video, devi impostare questa proprietà su true, in modo che il sistema esegua in modo efficiente e automatico la copia del fotogramma di input nel fotogramma di output.If your app does not modify the video frames (for example, an effect that only performs analysis of the video frames), you should set this property to true, which will cause the system to efficiently copy the frame input to the frame output for you.

Suggerimento

Quando la proprietà IsReadOnly è impostata su true, il sistema copia il fotogramma di input nel fotogramma di output prima di chiamare ProcessFrame.When the IsReadOnly property is set to true, the system copies the input frame to the output frame before ProcessFrame is called. L'impostazione della proprietà IsReadOnly su true non ti impedisce di scrivere nei fotogrammi di output dell'effetto in ProcessFrame.Setting the IsReadOnly property to true does not restrict you from writing to the effect's output frames in ProcessFrame.

public bool IsReadOnly { get { return false; } }

Metodo SetEncodingPropertiesSetEncodingProperties method

Il sistema chiama SetEncodingProperties sull'effetto per indicare le proprietà di codifica per il flusso video su cui è in funzione l'effetto.The system calls SetEncodingProperties on your effect to let you know the encoding properties for the video stream upon which the effect is operating. Questo metodo fornisce anche un riferimento al dispositivo Direct3D usato per il rendering hardware.This method also provides a reference to the Direct3D device used for hardware rendering. L'uso di questo dispositivo è illustrato nell'esempio di elaborazione hardware più avanti in questo articolo.The usage of this device is shown in the hardware processing example later in this article.

private VideoEncodingProperties encodingProperties;
public void SetEncodingProperties(VideoEncodingProperties encodingProperties, IDirect3DDevice device)
{
    this.encodingProperties = encodingProperties;
}

Proprietà SupportedEncodingPropertiesSupportedEncodingProperties property

Il sistema verifica la proprietà SupportedEncodingProperties per determinare quali proprietà di codifica sono supportate dall'effetto.The system checks the SupportedEncodingProperties property to determine which encoding properties are supported by your effect. Tieni presente che se il consumer dell'effetto non può codificare il video usando le proprietà specificate, chiamerà Close sull'effetto e rimuoverà l'effetto dalla pipeline del video.Note that if the consumer of your effect can't encode video using the properties you specify, it will call Close on your effect and will remove your effect from the video pipeline.

public IReadOnlyList<VideoEncodingProperties> SupportedEncodingProperties
{            
    get
    {
        var encodingProperties = new VideoEncodingProperties();
        encodingProperties.Subtype = "ARGB32";
        return new List<VideoEncodingProperties>() { encodingProperties };

        // If the list is empty, the encoding type will be ARGB32.
        // return new List<VideoEncodingProperties>();
    }
}

Nota

Se configuri SupportedEncodingProperties in modo che restituisca un elenco vuoto di oggetti VideoEncodingProperties, il sistema userà la codifica ARGB32 per impostazione predefinita.If you return an empty list of VideoEncodingProperties objects from SupportedEncodingProperties, the system will default to ARGB32 encoding.

 

Proprietà SupportedMemoryTypesSupportedMemoryTypes property

Il sistema verifica la proprietà SupportedMemoryTypes per determinare se l'effetto accederà ai fotogrammi video nella memoria software o nella memoria hardware (GPU).The system checks the SupportedMemoryTypes property to determine whether your effect will access video frames in software memory or in hardware (GPU) memory. Se si restituisce MediaMemoryTypes. CPU, all'effetto verranno passati i frame di input e di output che contengono dati immagine negli oggetti SoftwareBitmap .If you return MediaMemoryTypes.Cpu, your effect will be passed input and output frames that contain image data in SoftwareBitmap objects. Se restituisci MediaMemoryTypes.Gpu, all'effetto verranno passati i fotogrammi di input e di output che contengono i dati immagine in oggetti IDirect3DSurface.If you return MediaMemoryTypes.Gpu, your effect will be passed input and output frames that contain image data in IDirect3DSurface objects.

public MediaMemoryTypes SupportedMemoryTypes { get { return MediaMemoryTypes.Cpu; } }

Nota

Se specifichi MediaMemoryTypes.GpuAndCpu, il sistema userà la memoria GPU o la memoria di sistema, a seconda di quella che risulta più efficiente per la pipeline.If you specify MediaMemoryTypes.GpuAndCpu, the system will use either GPU or system memory, whichever is more efficient for the pipeline. Quando usi questo valore, devi controllare nel metodo ProcessFrame se l'oggetto SoftwareBitmap o IDirect3DSurface passato al metodo contiene i dati e quindi elaborare di conseguenza il fotogramma.When using this value, you must check in the ProcessFrame method to see whether the SoftwareBitmap or IDirect3DSurface passed into the method contains data, and then process the frame accordingly.

 

Proprietà TimeIndependentTimeIndependent property

La proprietà TimeIndependent consente al sistema di verificare se l'effetto non richiede un intervallo uniforme.The TimeIndependent property lets the system know if your effect does not require uniform timing. Se impostata su true, il sistema può usare ottimizzazioni per migliorare le prestazioni dell'effetto.When set to true, the system can use optimizations that enhance effect performance.

public bool TimeIndependent { get { return true; } }

Metodo SetPropertiesSetProperties method

Il metodo seproperties consente all'app che usa l'effetto di modificare i parametri di effetto.The SetProperties method allows the app that is using your effect to adjust effect parameters. Le proprietà vengono passate come mappa IPropertySet dei nomi e dei valori delle proprietà.Properties are passed as an IPropertySet map of property names and values.

private IPropertySet configuration;
public void SetProperties(IPropertySet configuration)
{
    this.configuration = configuration;
}

Questo semplice esempio attenuerà i pixel in ogni fotogramma video in base al valore specificato.This simple example will dim the pixels in each video frame according to a specified value. Viene dichiarata una proprietà e si usa TryGetValue per recuperare il valore impostato dall'app chiamante.A property is declared and TryGetValue is used to get the value set by the calling app. Se non è stato impostato alcun valore, viene usato il valore predefinito 0,5.If no value was set, a default value of .5 is used.

public double FadeValue
{
    get
    {
        object val;
        if (configuration != null && configuration.TryGetValue("FadeValue", out val))
        {
            return (double)val;
        }
        return .5;
    }
}

Metodo ProcessFrameProcessFrame method

Il metodo ProcessFrame è il punto in cui l'effetto modifica i dati dell'immagine del video.The ProcessFrame method is where your effect modifies the image data of the video. Il metodo viene chiamato una sola volta per ogni fotogramma e al metodo viene passato un oggetto ProcessVideoFrameContext.The method is called once per frame and is passed a ProcessVideoFrameContext object. Questo oggetto contiene un oggetto VideoFrame di input con il fotogramma in ingresso da elaborare e un oggetto VideoFrame di output in cui scrivere i dati immagine che verranno passati al resto della pipeline video.This object contains an input VideoFrame object that contains the incoming frame to be processed and an output VideoFrame object to which you write image data that will be passed on to rest of the video pipeline. Ognuno di questi oggetti VideoFrame ha una proprietà SoftwareBitmap e una proprietà Direct3DSurface, ma quale di queste può essere usata dipende dal valore restituito dalla proprietà SupportedMemoryTypes.Each of these VideoFrame objects has a SoftwareBitmap property and a Direct3DSurface property, but which of these can be used is determined by the value you returned from the SupportedMemoryTypes property.

Questo esempio mostra una semplice implementazione del metodo ProcessFrame con elaborazione software.This example shows a simple implementation of the ProcessFrame method using software processing. Per altre informazioni sull'uso di oggetti SoftwareBitmap, vedi Creazione di immagini.For more information about working with SoftwareBitmap objects, see Imaging. Un'implementazione di esempio di ProcessFrame con elaborazione hardware è illustrata più avanti in questo articolo.An example ProcessFrame implementation using hardware processing is shown later in this article.

Per l'accesso al buffer di dati di un oggetto SoftwareBitmap è necessaria l'interoperabilità COM, quindi devi includere lo spazio dei nomi System.Runtime.InteropServices nel file della classe dell'effetto.Accessing the data buffer of a SoftwareBitmap requires COM interop, so you should include the System.Runtime.InteropServices namespace in your effect class file.

using System.Runtime.InteropServices;

Aggiungi il codice seguente all'interno dello spazio dei nomi per l'effetto allo scopo di importare l'interfaccia per l'accesso al buffer di immagini.Add the following code inside the namespace for your effect to import the interface for accessing the image buffer.

[ComImport]
[Guid("5B0D3235-4DBA-4D44-865E-8F1D0E4FD04D")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
unsafe interface IMemoryBufferByteAccess
{
    void GetBuffer(out byte* buffer, out uint capacity);
}

Nota

Dato che questa tecnica accede a un buffer di immagini nativo e non gestito, dovrai configurare il progetto per consentire il codice unsafe.Because this technique accesses a native, unmanaged image buffer, you will need to configure your project to allow unsafe code.

  1. In Esplora soluzioni fai clic con il pulsante destro del mouse sul progetto VideoEffectComponent e scegli Proprietà.In Solution Explorer, right-click the VideoEffectComponent project and select Properties.
  2. Selezionare la scheda Build (Compilazione).Select the Build tab.
  3. Selezionare la casella di controllo Consenti codice unsafe .Select the Allow unsafe code check box.

 

Ora puoi aggiungere l'implementazione del metodo ProcessFrame.Now you can add the ProcessFrame method implementation. Questo metodo ottiene prima di tutto un oggetto BitmapBuffer dalle bitmap software di input e output.First, this method obtains a BitmapBuffer object from both the input and output software bitmaps. Nota che il fotogramma di output viene aperto per la scrittura e il fotogramma di input per la lettura.Note that the output frame is opened for writing and the input for reading. Viene quindi ottenuto un IMemoryBufferReference per ogni buffer chiamando CreateReference.Next, an IMemoryBufferReference is obtained for each buffer by calling CreateReference. Il buffer dei dati effettivo viene poi ottenuto tramite il cast degli oggetti IMemoryBufferReference con l'interfaccia di interoperabilità COM definita in precedenza, IMemoryByteAccess, e chiamando quindi GetBuffer.Then, the actual data buffer is obtained by casting the IMemoryBufferReference objects as the COM interop interface defined above, IMemoryByteAccess, and then calling GetBuffer.

Dopo aver ottenuto i buffer dei dati, puoi leggere dal buffer di input e scrivere nel buffer di output.Now that the data buffers have been obtained, you can read from the input buffer and write to the output buffer. Il layout del buffer viene ottenuto chiamando GetPlaneDescription, che fornisce informazioni sulla larghezza, lo stride e l'offset iniziale del buffer.The layout of the buffer is obtained by calling GetPlaneDescription, which provides information on the width, stride, and initial offset of the buffer. I bit per pixel sono determinati dalle proprietà di codifica impostate in precedenza con il metodo SetEncodingProperties .The bits per pixel is determined by the encoding properties set previously with the SetEncodingProperties method. Le informazioni sul formato del buffer vengono usate per trovare l'indice nel buffer per ogni pixel.The buffer format information is used to find the index into the buffer for each pixel. Il valore dei pixel dal buffer di origine viene copiato nel buffer di destinazione, con i valori di colore moltiplicati per la proprietà FadeValue definita per questo effetto in modo da attenuarli in base al valore specificato.The pixel value from the source buffer is copied into the target buffer, with the color values being multiplied by the FadeValue property defined for this effect to dim them by the specified amount.

public unsafe void ProcessFrame(ProcessVideoFrameContext context)
{
    using (BitmapBuffer buffer = context.InputFrame.SoftwareBitmap.LockBuffer(BitmapBufferAccessMode.Read))
    using (BitmapBuffer targetBuffer = context.OutputFrame.SoftwareBitmap.LockBuffer(BitmapBufferAccessMode.Write))
    {
        using (var reference = buffer.CreateReference())
        using (var targetReference = targetBuffer.CreateReference())
        {
            byte* dataInBytes;
            uint capacity;
            ((IMemoryBufferByteAccess)reference).GetBuffer(out dataInBytes, out capacity);

            byte* targetDataInBytes;
            uint targetCapacity;
            ((IMemoryBufferByteAccess)targetReference).GetBuffer(out targetDataInBytes, out targetCapacity);

            var fadeValue = FadeValue;

            // Fill-in the BGRA plane
            BitmapPlaneDescription bufferLayout = buffer.GetPlaneDescription(0);
            for (int i = 0; i < bufferLayout.Height; i++)
            {
                for (int j = 0; j < bufferLayout.Width; j++)
                {

                    byte value = (byte)((float)j / bufferLayout.Width * 255);

                    int bytesPerPixel = 4; 
                    if (encodingProperties.Subtype != "ARGB32")
                    {
                        // If you support other encodings, adjust index into the buffer accordingly
                    }
                    

                    int idx = bufferLayout.StartIndex + bufferLayout.Stride * i + bytesPerPixel * j;

                    targetDataInBytes[idx + 0] = (byte)(fadeValue * (float)dataInBytes[idx + 0]);
                    targetDataInBytes[idx + 1] = (byte)(fadeValue * (float)dataInBytes[idx + 1]);
                    targetDataInBytes[idx + 2] = (byte)(fadeValue * (float)dataInBytes[idx + 2]);
                    targetDataInBytes[idx + 3] = dataInBytes[idx + 3];
                }
            }
        }
    }
}

Implementare l'interfaccia IBasicVideoEffect tramite elaborazione hardwareImplement the IBasicVideoEffect interface using hardware processing

La creazione di un effetto video personalizzato con elaborazione hardware (GPU) è quasi identica all'uso dell'elaborazione software come descritto sopra.Creating a custom video effect by using hardware (GPU) processing is almost identical to using software processing as described above. Questa sezione mostra le poche differenze esistenti per un effetto che usa l'elaborazione hardware.This section will show the few differences in an effect that uses hardware processing. Questo esempio usa l'API di Windows Runtime Win2D.This example uses the Win2D Windows Runtime API. Per altre informazioni sull'uso di Win2D, vedi la documentazione su Win2D.For more information about using Win2D, see the Win2D documentation.

Usa i passaggi seguenti per aggiungere il pacchetto NuGet Win2D al progetto creato come descritto nella sezione Aggiungere un effetto personalizzato all'app all'inizio di questo articolo.Use the following steps to add the Win2D NuGet package to the project you created as described in the Add a custom effect to your app section at the beginning of this article.

Per aggiungere il pacchetto NuGet Win2D al progetto dell'effettoTo add the Win2D NuGet package to your effect project

  1. In Esplora soluzioni fai clic con il pulsante destro del mouse sul progetto VideoEffectComponent e scegli Gestisci pacchetti NuGet.In Solution Explorer, right-click the VideoEffectComponent project and select Manage NuGet Packages.
  2. Nella parte superiore della finestra seleziona la scheda Sfoglia.At the top of the window, select the Browse tab.
  3. Nella casella di ricerca immetti Win2D.In the search box, enter Win2D.
  4. Seleziona Win2D.uwp e quindi seleziona Installa nel riquadro destro.Select Win2D.uwp, and then select Install in the right pane.
  5. Nella finestra di dialogo Rivedi modifiche viene mostrato il pacchetto da installare.The Review Changes dialog shows you the package to be installed. Fare clic su OK.Click OK.
  6. Accetta la licenza per il pacchetto.Accept the package license.

Oltre agli spazi dei nomi inclusi nel progetto di base, dovrai includere gli spazi dei nomi seguenti forniti da Win2D.In addition to the namespaces included in the basic project setup, you will need to include the following namespaces provided by Win2D.

using Microsoft.Graphics.Canvas.Effects;
using Microsoft.Graphics.Canvas;

Poiché questo effetto utilizzerà la memoria GPU per operare sui dati dell'immagine, è necessario restituire MediaMemoryTypes. GPU dalla proprietà SupportedMemoryTypes .Because this effect will use GPU memory for operating on the image data, you should return MediaMemoryTypes.Gpu from the SupportedMemoryTypes property.

public MediaMemoryTypes SupportedMemoryTypes { get { return MediaMemoryTypes.Gpu; } }

Imposta le proprietà di codifica supportate dal tuo effetto con la proprietà SupportedEncodingProperties.Set the encoding properties that your effect will support with the SupportedEncodingProperties property. Con Win2D devi usare la codifica ARGB32.When working with Win2D, you must use ARGB32 encoding.

public IReadOnlyList<VideoEncodingProperties> SupportedEncodingProperties {
    get
    {
        var encodingProperties = new VideoEncodingProperties();
        encodingProperties.Subtype = "ARGB32";
        return new List<VideoEncodingProperties>() { encodingProperties };
    }
}

Usa il metodo SetEncodingProperties per creare un nuovo oggetto CanvasDevice Win2D dall'oggetto IDirect3DDevice passato al metodo.Use the SetEncodingProperties method to create a new Win2D CanvasDevice object from the IDirect3DDevice passed into the method.

private CanvasDevice canvasDevice;
public void SetEncodingProperties(VideoEncodingProperties encodingProperties, IDirect3DDevice device)
{
    canvasDevice = CanvasDevice.CreateFromDirect3D11Device(device);
}

L'implementazione di SetProperties è identica all'esempio di elaborazione software precedente.The SetProperties implementation is identical to the previous software processing example. Questo esempio usa una proprietà BlurAmount per configurare un effetto di sfocatura Win2D.This example uses a BlurAmount property to configure a Win2D blur effect.

private IPropertySet configuration;
public void SetProperties(IPropertySet configuration)
{
    this.configuration = configuration;
}
public double BlurAmount
{
    get
    {
        object val;
        if (configuration != null && configuration.TryGetValue("BlurAmount", out val))
        {
            return (double)val;
        }
        return 3;
    }
}

L'ultimo passaggio consiste nell'implementare il metodo ProcessFrame che elabora effettivamente i dati dell'immagine.The last step is to implement the ProcessFrame method that actually processes the image data.

Con le API Win2D, viene creata una CanvasBitmap dalla proprietà Direct3DSurface del fotogramma di input.Using Win2D APIs, a CanvasBitmap is created from the input frame's Direct3DSurface property. Viene creato un oggetto CanvasRenderTarget dalla proprietà Direct3DSurface del frame di output e un oggetto CanvasDrawingSession da questa destinazione di rendering.A CanvasRenderTarget is created from the output frame's Direct3DSurface and a CanvasDrawingSession is created from this render target. Viene inizializzato un nuovo GaussianBlurEffect Win2D usando la proprietà BlurAmount esposta dal nostro effetto tramite SetProperties.A new Win2D GaussianBlurEffect is initialized, using the BlurAmount property our effect exposes via SetProperties. Infine, viene chiamato il metodo CanvasDrawingSession.DrawImage per disegnare la bitmap di input per la destinazione di rendering con l'effetto di sfocatura.Finally, the CanvasDrawingSession.DrawImage method is called to draw the input bitmap to the render target using the blur effect.

public void ProcessFrame(ProcessVideoFrameContext context)
{

    using (CanvasBitmap inputBitmap = CanvasBitmap.CreateFromDirect3D11Surface(canvasDevice, context.InputFrame.Direct3DSurface))
    using (CanvasRenderTarget renderTarget = CanvasRenderTarget.CreateFromDirect3D11Surface(canvasDevice, context.OutputFrame.Direct3DSurface))
    using (CanvasDrawingSession ds = renderTarget.CreateDrawingSession())
    {


        var gaussianBlurEffect = new GaussianBlurEffect
        {
            Source = inputBitmap,
            BlurAmount = (float)BlurAmount,
            Optimization = EffectOptimization.Speed
        };

        ds.DrawImage(gaussianBlurEffect);

    }
}

Aggiunta dell'effetto personalizzato all'appAdding your custom effect to your app

Per usare l'effetto video dalla tua app, devi aggiungere un riferimento al progetto dell'effetto nella tua app.To use your video effect from your app, you must add a reference to the effect project to your app.

  1. In Esplora soluzioni, all'interno del progetto dell'app, fai clic con il pulsante destro del mouse su Riferimenti e scegli Aggiungi riferimento.In Solution Explorer, under your app project, right-click References and select Add reference.
  2. Espandi la scheda Progetti, seleziona Soluzione e quindi seleziona la casella di controllo corrispondente al nome del progetto dell'effetto.Expand the Projects tab, select Solution, and then select the check box for your effect project name. Per questo esempio, il nome è VideoEffectComponent.For this example, the name is VideoEffectComponent.
  3. Fare clic su OK.Click OK.

Aggiungere l'effetto personalizzato a un flusso video della fotocameraAdd your custom effect to a camera video stream

Puoi configurare un semplice flusso di anteprima dalla fotocamera seguendo i passaggi nell'articolo Accesso semplice all'anteprima della fotocamera.You can set up a simple preview stream from the camera by following the steps in the article Simple camera preview access. Seguendo questi passaggi verrà fornito un oggetto MediaCapture inizializzato usato per accedere al flusso video della fotocamera.Following those steps will provide you with an initialized MediaCapture object that is used to access the camera's video stream.

Per aggiungere l'effetto video personalizzato a un flusso della fotocamera, crea prima di tutto un nuovo oggetto VideoEffectDefinition, passando lo spazio dei nomi e il nome della classe per l'effetto.To add your custom video effect to a camera stream, first create a new VideoEffectDefinition object, passing in the namespace and class name for your effect. Chiama quindi il metodo AddVideoEffect dell'oggetto MediaCapture per aggiungere l'effetto al flusso specificato.Next, call the MediaCapture object's AddVideoEffect method to add your effect to the specified stream. Questo esempio usa il valore MediaStreamType.VideoPreview per specificare che l'effetto deve essere aggiunto al flusso di anteprima.This example uses the MediaStreamType.VideoPreview value to specify that the effect should be added to the preview stream. Se la tua app supporta l'acquisizione di video, potresti usare anche MediaStreamType.VideoRecord per aggiungere l'effetto al flusso di acquisizione.If your app supports video capture, you could also use MediaStreamType.VideoRecord to add the effect to the capture stream. AddVideoEffect restituisce un oggetto IMediaExtension che rappresenta l'effetto personalizzato.AddVideoEffect returns an IMediaExtension object representing your custom effect. Puoi usare il metodo SetProperties per impostare la configurazione per l'effetto.You can use the SetProperties method to set the configuration for your effect.

Dopo che l'effetto è stato aggiunto, per avviare il flusso di anteprima viene chiamato StartPreviewAsync .After the effect has been added, StartPreviewAsync is called to start the preview stream.

var videoEffectDefinition = new VideoEffectDefinition("VideoEffectComponent.ExampleVideoEffect");

IMediaExtension videoEffect =
   await mediaCapture.AddVideoEffectAsync(videoEffectDefinition, MediaStreamType.VideoPreview);

videoEffect.SetProperties(new PropertySet() { { "FadeValue", .25 } });

await mediaCapture.StartPreviewAsync();

Aggiungere l'effetto personalizzato a un clip in una composizione multimedialeAdd your custom effect to a clip in a MediaComposition

Per indicazioni generazioni per la creazione di composizioni multimediali da clip video, vedi Composizioni multimediali e modifica.For general guidance for creating media compositions from video clips, see Media compositions and editing. Il frammento di codice seguente illustra la creazione di una composizione multimediale semplice che usa un effetto video personalizzato.The following code snippet shows the creation of a simple media composition that uses a custom video effect. Un oggetto MediaClip viene creato chiamando CreateFromFileAsync, passando un file video selezionato dall'utente con un FileOpenPickere la clip viene aggiunta a un nuovo MediaComposition.A MediaClip object is created by calling CreateFromFileAsync, passing in a video file that was selected by the user with a FileOpenPicker, and the clip is added to a new MediaComposition. Successivamente, viene creato un nuovo oggetto VideoEffectDefinition , passando lo spazio dei nomi e il nome della classe per l'effetto al costruttore.Next a new VideoEffectDefinition object is created, passing in the namespace and class name for your effect to the constructor. La definizione dell'effetto viene infine aggiunta alla raccolta VideoEffectDefinitions dell'oggetto MediaClip.Finally, the effect definition is added to the VideoEffectDefinitions collection of the MediaClip object.

MediaComposition composition = new MediaComposition();
var clip = await MediaClip.CreateFromFileAsync(pickedFile);
composition.Clips.Add(clip);

var videoEffectDefinition = new VideoEffectDefinition("VideoEffectComponent.ExampleVideoEffect", new PropertySet() { { "FadeValue", .5 } });

clip.VideoEffectDefinitions.Add(videoEffectDefinition);