Effets

Que sont les effets Direct2D ?

Vous pouvez utiliser Direct2D pour appliquer un ou plusieurs effets de haute qualité à une image ou à un ensemble d'images. Les API d'effets sont basées sur Direct3D 11 et tirent parti des fonctionnalités du GPU pour le traitement des images. Vous pouvez enchaîner les effets dans un graphique d'effets et composer ou mélanger la sortie des effets.

Un effet Direct2D effectue une tâche d'imagerie, comme changer la luminosité, dé-saturer une image ou créer une ombre portée. Les effets peuvent accepter zéro ou plusieurs images en entrée, exposer plusieurs propriétés qui contrôlent leur fonctionnement et générer une seule image en sortie.

Chaque effet crée un graphique de transformation interne composé de transformations individuelles. Chaque transformation représente une seule opération sur l'image. L'objectif principal d'une transformation est d'héberger les nuanceurs qui sont exécutés pour chaque pixel de sortie. Ces nuanceurs peuvent être des nuanceurs de pixels, des nuanceurs de vertex, l'étape de fusion d'un GPU et des nuanceurs de calcul.

Les effets intégrés de Direct2D et les effets personnalisés que vous pouvez créer à l'aide de l'API d'effets personnalisés fonctionnent de cette manière.

Il existe toute une série d'effets intégrés dans des catégories telles que celles présentées ici. Voir la section Effets intégrés pour une liste complète.

Vous pouvez appliquer des effets à n'importe quelle image bitmap, y compris les images chargées par le composant d'imagerie Windows (WIC), les primitives dessinées par Direct2D, le texte provenant de DirectWrite ou les scènes rendues par Direct3D.

Avec les effets Direct2D, vous pouvez écrire vos propres effets que vous pouvez utiliser pour vos applications. Un cadre d'effets personnalisés vous permet d'utiliser les fonctionnalités du GPU telles que les nuanceurs de pixels, les nuanceurs de sommets et l'unité de mélange. Vous pouvez également inclure d'autres effets intégrés ou personnalisés dans votre effet personnalisé. Le cadre permettant de créer des effets personnalisés est le même que celui utilisé pour créer les effets intégrés de Direct2D. L'API de création d'effets Direct2D fournit un ensemble d'interfaces permettant de créer et d'enregistrer des effets.

Autres rubriques sur les effets

Le reste de cette rubrique explique les bases des effets Direct2D, comme l'application d'un effet à une image. Le tableau ci-dessous contient des liens vers d'autres rubriques sur les effets.

Sujet Description
Liaison de nuanceurs d’effet
Direct2D utilise une optimisation appelée liaison de shaders d'effets qui combine plusieurs passes de rendu de graphes d'effets en une seule passe.
Effets personnalisés
Vous montre comment écrire vos propres effets personnalisés à l'aide du langage HLSL standard.
Comment charger une image dans Direct2D Effects à l'aide du sélecteur de fichiers?
Montre comment utiliser Windows::Storage::Pickers::FileOpenPicker pour charger une image dans les effets Direct2D.
Guide pratique pour enregistrer le contenu Direct2D dans un fichier image
Cette rubrique montre comment utiliser IWICImageEncoder pour enregistrer un contenu sous la forme d'une ID2D1Image dans un fichier image codé tel que JPEG.
Comment appliquer des effets aux primitives
Cette rubrique montre comment appliquer une série d'effets aux primitives Direct2D et DirectWrite.
Contrôle de la précision et de l'écrêtage numérique dans les graphiques d'effets
Les applications qui effectuent le rendu d'effets à l'aide de Direct2D doivent veiller à atteindre le niveau de qualité et de prévisibilité souhaité en ce qui concerne la précision numérique.

Appliquer un effet à une image

Vous pouvez utiliser l'API d'effets Direct2D pour appliquer des transformations à des images.

Remarque

Cet exemple suppose que vous avez déjà créé les objets ID2D1DeviceContext et IWICBitmapSource. Pour plus d'informations sur la création de ces objets, voir Comment charger une image dans les effets Direct2D à l'aide du FilePicker et Appareils et contextes d'appareils.

  1. Déclarez une variable ID2D1Effect, puis créez un effet source bitmap à l'aide de la méthode ID2DDeviceContext::CreateEffect.

        ComPtr<ID2D1Effect> bitmapSourceEffect;
    
        DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1BitmapSource, &bitmapSourceEffect));
    
  2. Définissez la propriété BitmapSource à la source bitmap WIC à l'aide de la fonction ID2D1Effect::SetValue.

            DX::ThrowIfFailed(m_bitmapSourceEffect->SetValue(D2D1_BITMAPSOURCE_PROP_WIC_BITMAP_SOURCE, m_wicBitmapSource.Get()));
    
  3. Déclarez une variable ID2D1Effect et créez ensuite l'effet de flou gaussien.

        ComPtr<ID2D1Effect> gaussianBlurEffect;
    
        DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1GaussianBlur, &gaussianBlurEffect));
    
  4. Définissez l'entrée pour recevoir l'image de l'effet bitmap source. Définissez la quantité de flou la méthode SetValue et la propriété de l'écart-type.

        gaussianBlurEffect->SetInputEffect(0, bitmapSourceEffect.Get());
    
        DX::ThrowIfFailed(gaussianBlurEffect->SetValue(D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION, 6.0f));
    
  5. Utilisez le contexte de l'appareil pour dessiner la sortie de l'image résultante.

        m_d2dContext->BeginDraw();
    
        m_d2dContext->Clear(D2D1::ColorF(D2D1::ColorF::CornflowerBlue));
    
        // Draw the blurred image.
        m_d2dContext->DrawImage(gaussianBlurEffect.Get());
    
        HRESULT hr = m_d2dContext->EndDraw();
    

    La méthode DrawImage doit être appelée entre les appels ID2DDeviceContext::BeginDraw et EndDraw, comme les autres opérations de rendu Direct2D. DrawImage peut prendre une image ou la sortie d'un effet et la rendre sur la surface cible.

Transformations spatiales

Direct2D fournit des effets intégrés qui peuvent transformer les images dans l'espace 2D et 3D, ainsi que les mettre à l'échelle. Les effets de mise à l'échelle et de transformation offrent différents niveaux de qualité tels que : le plus proche voisin, linéaire, cubique, linéaire multi-échantillon, anisotropique et cubique de haute qualité.

Remarque

Le mode anisotropique génère des mipmaps lors de la mise à l'échelle. Cependant, si vous attribuez la valeur true à la propriété Cached des effets entrant dans la transformation, les mipmaps ne seront pas générés à chaque fois pour des images suffisamment petites.

ComPtr<ID2D1Effect> affineTransformEffect;
DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D12DAffineTransform, &affineTransformEffect));

affineTransformEffect->SetInput(0, bitmap.Get());

D2D1_MATRIX_3X2_F matrix = D2D1::Matrix3x2F(0.9f, -0.1f,  0.1f, 0.9f, 8.0f, 45.0f);
DX::ThrowIfFailed(affineTransformEffect->SetValue(D2D1_2DAFFINETRANSFORM_PROP_TRANSFORM_MATRIX, matrix));

m_d2dContext->BeginDraw();
m_d2dContext->DrawImage(affineTransformEffect.Get());
m_d2dContext->EndDraw();

Cette utilisation de l'effet de transformation affine 2D fait légèrement pivoter l'image dans le sens inverse des aiguilles d'une montre.

Avant
Effet affine 2D avant l'image.
Après
Effet affine 2D après l'image.

Composer des images

Certains effets acceptent plusieurs entrées et les combinent en une seule image.

Les effets composite et composite arithmétique intégrés offrent différents modes. Pour plus d'informations, consultez la rubrique composite. L'effet de fusion dispose de plusieurs modes accélérés par le GPU.

ComPtr<ID2D1Effect> compositeEffect;
DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1Composite, &compositeEffect));

compositeEffect->SetInput(0, bitmap.Get());
compositeEffect->SetInput(1, bitmapTwo.Get());

m_d2dContext->BeginDraw();
m_d2dContext->DrawImage(compositeEffect.Get());
m_d2dContext->EndDraw();

L'effet composite combine les images de différentes manières en fonction du mode que vous avez spécifié.

Ajustements de pixels

Quelques effets Direct2D intégrés vous permettent de modifier les données des pixels. Par exemple, l'effet de matrice de couleur peut être utilisé pour modifier la couleur d'une image.

ComPtr<ID2D1Effect> colorMatrixEffect;
DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1ColorMatrix, &colorMatrixEffect));

colorMatrixEffect->SetInput(0, bitmap.Get());

D2D1_MATRIX_5X4_F matrix = D2D1::Matrix5x4F(0, 0, 1, 0,   0, 1, 0, 0,   1, 0, 0, 0,   0, 0, 0, 1,   0, 0, 0, 0);
DX::ThrowIfFailed(colorMatrixEffect->SetValue(D2D1_COLORMATRIX_PROP_COLOR_MATRIX, matrix));

m_d2dContext->BeginDraw();
m_d2dContext->DrawImage(colorMatrixEffect.Get());
m_d2dContext->EndDraw();

Ce code prend l'image et modifie la couleur comme indiqué dans les images d'exemple ci-dessous.

Avant
effet de matrice de couleur avant l'image.
Après
Effet de matrice de couleur après l'image.

Pour plus d'informations, reportez-vous à la section sur les effets intégrés de la couleur.

Construire des graphes d'effets

Vous pouvez enchaîner les effets pour transformer les images. Par exemple, le code ci-dessous applique une ombre et une transformation 2D, puis compose les résultats ensemble.

ComPtr<ID2D1Effect> shadowEffect;
ComPtr<ID2D1Effect> affineTransformEffect;
ComPtr<ID2D1Effect> compositeEffect;

DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1Shadow, &shadowEffect));
DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D12DAffineTransform, &affineTransformEffect));
DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1Composite, &compositeEffect));

shadowEffect->SetInput(0, bitmap.Get());
affineTransformEffect->SetInputEffect(0, shadowEffect.Get());

D2D1_MATRIX_3X2_F matrix = D2D1::Matrix3x2F::Translation(20, 20));

affineTransformEffect->SetValue(D2D1_2DAFFINETRANSFORM_PROP_TRANSFORM_MATRIX, matrix);

compositeEffect->SetInputEffect(0, affineTransformEffect.Get());
compositeEffect->SetInput(1, bitmap.Get());

m_d2dContext->BeginDraw();
m_d2dContext->DrawImage(compositeEffect.Get());
m_d2dContext->EndDraw();

Voici le résultat.

sortie de l'effet d'ombre.

Les effets prennent des objets ID2D1Image en entrée. Vous pouvez utiliser une ID2D1Bitmap car l'interface est dérivée de ID2D1Image. Vous pouvez également utiliser ID2D1Effect::GetOutput pour obtenir la sortie d'un objet ID2D1Effect sous la forme d'une image ID2D1 ou utiliser la méthode SetInputEffect, qui convertit la sortie pour vous. Dans la plupart des cas, un graphique d'effets se compose d'objets ID2D1Effect directement enchaînés, ce qui facilite l'application de plusieurs effets à une image pour créer des visuels attrayants.

Pour plus d'informations, voir Comment appliquer des effets aux primitives.

Exemple d'effets d'image de base Direct2D

Effets intégrés