Effekte

Was sind Direct2D-Effekte?

Sie können Direct2D verwenden, um einen oder mehrere hochwertige Effekte auf ein Bild oder eine Gruppe von Bildern anzuwenden. Die Effekt-APIs wurden auf Basis von Direct3D 11 erstellt und machen sich die Funktionen der GPU für die Bildverarbeitung zunutze. Sie können Effekte in einem Effektgraphen verketten und die Ausgabe von Effekten kombinieren oder mischen.

Ein Direct2D-Effekt führt eine Bildverarbeitungsaufgabe aus, z. B. die Änderung der Helligkeit, die Entsättigung eines Bildes oder das Erstellen eines Schlagschattens. Effekte können null oder mehr Eingabebilder entgegennehmen, mehrere Eigenschaften aufweisen, die ihren Prozess steuern, und ein einziges Ausgabebild erzeugen.

Jeder Effekt erstellt einen internen Transformations-Graphen, der aus einzelnen Transformationen besteht. Jede Transformation steht für eine einzelne Bildoperation. Der Hauptzweck einer Transformation besteht darin, die Shader aufzunehmen, die für jedes Ausgabepixel ausgeführt werden. Diese Shader können Pixel-Shader, Vertex-Shader, die Blending-Stage einer GPU und Compute-Shader umfassen.

Sowohl die in Direct2D integrierten Effekte als auch die angepassten Effekte, die Sie mit der API für angepasste Effekte erstellen können, funktionieren auf diese Weise.

Es gibt eine Reihe von integrierten Effekten aus Kategorien wie den hier genannten. Eine vollständige Liste finden Sie im Abschnitt Integrierte Effekte.

Sie können Effekte auf jede Bitmap anwenden, einschließlich: Bilder, die von Windows Imaging Component (WIC) geladen werden, von Direct2D gezeichnete Primitiven, Text von DirectWrite oder von Direct3D gerenderte Szenen.

Mit Direct2D-Effekten können Sie Ihre eigenen Effekte schreiben, die Sie für Ihre Anwendungen verwenden können. Ein angepasstes Effekt-Framework bietet Ihnen die Möglichkeit, GPU-Funktionen wie Pixel-Shader, Vertex-Shader und die Blending-Einheit zu nutzen. Sie können außerdem andere integrierte oder angepasste Effekte in Ihren benutzerdefinierten Effekt integrieren. Das Framework zum Erstellen von angepassten Effekten ist dasselbe, mit dem auch die integrierten Effekte von Direct2D erstellt wurden. Die Direct2D-Effektautoren-API bietet eine Reihe von Schnittstellen zum Erstellen und Registrieren von Effekten.

Weitere Themen zu Effekten

Der Rest dieses Themas erklärt die Grundlagen von Direct2D-Effekten, wie z. B. die Anwendung eines Effekts auf ein Bild. Die Tabelle hier enthält Links zu weiteren Themen über Effekte.

Thema Beschreibung
Effektshader-Verknüpfung
Direct2D verwendet eine Optimierung namens Effekt-Shader-Linking, die mehrere Rendering-Durchgänge des Effektgraphen in einem einzigen Durchgang kombiniert.
Benutzerdefinierte Effekte
Zeigt Ihnen, wie Sie Ihre eigenen angepassten Effekte mit Standard-HLSL schreiben können.
So laden Sie ein Bild mit dem FilePicker in Direct2D-Effekte
Zeigt, wie Sie Windows::Storage::Pickers::FileOpenPicker verwenden, um ein Bild in Direct2D-Effekte zu laden.
Speichern von Direct2D-Inhalten in einer Bilddatei
Dieses Thema zeigt, wie Sie IWICImageEncoder verwenden, um Inhalte in der Form eines ID2D1Image in einer kodierten Bilddatei wie JPEG zu speichern.
So wenden Sie Effekte auf Primitiven an
Dieses Thema zeigt, wie Sie eine Reihe von Effekten auf Direct2D und DirectWrite-Primitiven anwenden können.
Präzision und numerisches Clipping in Effektgraphen steuern
Anwendungen, die Effekte mit Direct2D rendern, müssen darauf achten, die gewünschte Qualität und Vorhersagbarkeit in Bezug auf die numerische Präzision zu erreichen.

Anwenden eines Effekts auf ein Bild

Sie können die Direct2D-Effekt-API verwenden, um Transformationen auf Bilder anzuwenden.

Hinweis

Dieses Beispiel setzt voraus, dass Sie bereits die Objekte ID2D1DeviceContext und IWICBitmapSource erstellt haben. Weitere Informationen zum Erstellen dieser Objekte finden Sie unter So laden Sie ein Bild mit dem FilePicker in Direct2D-Effekte und Geräte und Gerätekontexte.

  1. Deklarieren Sie eine ID2D1Effect-Variable, und erstellen Sie dann einen BitmapSource-Effekt mit der ID2DDeviceContext::CreateEffect-Methode.

        ComPtr<ID2D1Effect> bitmapSourceEffect;
    
        DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1BitmapSource, &bitmapSourceEffect));
    
  2. Legen Sie die Eigenschaft BitmapSource mit der Methode ID2D1Effect::SetValue auf die WIC-Bitmap-Quelle fest.

            DX::ThrowIfFailed(m_bitmapSourceEffect->SetValue(D2D1_BITMAPSOURCE_PROP_WIC_BITMAP_SOURCE, m_wicBitmapSource.Get()));
    
  3. Deklarieren Sie eine ID2D1Effect-Variable, und erstellen Sie dann den gaußschen Weichzeichner-Effekt.

        ComPtr<ID2D1Effect> gaussianBlurEffect;
    
        DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1GaussianBlur, &gaussianBlurEffect));
    
  4. Legen Sie die Eingabe fest, um das Bild aus dem Bitmap-Quellen-Effekt zu erhalten. Legen Sie den Unschärfegrad mit der Methode SetValue und die Eigenschaft standard deviation fest.

        gaussianBlurEffect->SetInputEffect(0, bitmapSourceEffect.Get());
    
        DX::ThrowIfFailed(gaussianBlurEffect->SetValue(D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION, 6.0f));
    
  5. Verwenden Sie den Gerätekontext, um die resultierende Bildausgabe zu zeichnen.

        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();
    

    Die Methode DrawImage muss wie andere Direct2D-Rendervorgänge zwischen den Aufrufen ID2DDeviceContext::BeginDraw und EndDraw aufgerufen werden. DrawImage kann ein Bild oder die Ausgabe eines Effekts verwenden und es auf die Oberfläche des Ziels rendern.

Spatiale Transformationen

Direct2D bietet integrierte Effekte, die Bilder im 2D- und 3D-Raum transformieren und skalieren können. Die Skalierungs- und Transformationseffekte bieten verschiedene Qualitätsstufen wie: nächster Nachbar, linear, kubisch, linear mit mehreren Samples, anisotrop und kubisch mit hoher Qualität.

Hinweis

Der anisotrope Modus erzeugt bei der Skalierung Mipmaps. Wenn Sie jedoch bei den Effekten, die der Transformation übergeben werden, die Eigenschaft Cached auf WAHR festlegen, werden die Mipmaps bei ausreichend kleinen Bildern nicht jedes Mal erzeugt.

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();

Bei dieser Verwendung des Effekts „Affine 2D-Transformation“ wird die Bitmap leicht gegen den Uhrzeigersinn gedreht.

Vorher
Vor Effekt 2D-Affin.
After
Nach Effekt 2D-Affin.

Zusammenführen von Bildern

Einige Effekte akzeptieren mehrere Eingaben und fügen sie zu einem einzigen Bild zusammen.

Die integrierten Effekte Composite und Arithmetische Kombination bieten verschiedene Modi. Weitere Informationen finden Sie im Thema Composite. Der Effekt Blending verfügt über eine Reihe von GPU-beschleunigten Modi.

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();

Der Composite-Effekt kombiniert Bilder auf verschiedene Arten, je nachdem, welchen Modus Sie angeben.

Pixel-Anpassungen

Es gibt ein paar integrierte Direct2D-Effekte, die Ihnen die Möglichkeit bieten, die Pixeldaten zu verändern. Mit dem Farbmatrix-Effekt können Sie zum Beispiel die Farbe eines Bildes ändern.

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();

Dieser Code nimmt das Bild und ändert die Farbe wie in den Beispielbildern hier gezeigt.

Vorher
Vor Farbmatrix-Effekt.
After
Nach Farbmatrix-Effekt.

Weitere Informationen finden Sie im Abschnitt Integrierte Farbeffekte.

Erstellen von Effektgraphen

Sie können Effekte miteinander verketten, um Bilder zu transformieren. Der Code hier wendet zum Beispiel einen Schatten und eine 2D-Transformation an und führt die Ergebnisse dann zu einem Composite zusammen.

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();

Hier ist das Ergebnis.

Ausgabe des Schatteneffekts.

Effekte nehmen ID2D1Image-Objekte als Eingabe. Sie können eine ID2D1Bitmap verwenden, da die Schnittstelle von ID2D1Image abgeleitet ist. Sie können auch ID2D1Effect::GetOutput verwenden, um die Ausgabe eines ID2D1Effect-Objekts als ID2D1Image zu erhalten, oder die Methode SetInputEffect verwenden, die die Ausgabe für Sie konvertiert. In den meisten Fällen besteht ein Effektgraph aus ID2D1Effect-Objekten, die direkt miteinander verkettet sind. So können Sie ganz einfach mehrere Effekte auf ein Bild anwenden, um überzeugende visuelle Effekte zu erstellen.

Weitere Informationen finden Sie unter So wenden Sie Effekte auf Primitiven an.

Beispiel für grundlegende Direct2D-Bildeffekte

Integrierte Effekte