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 Effekte-APIs basieren auf Direct3D 11 und nutzen GPU-Features für die Bildverarbeitung. Sie können Effekte in einem Effektdiagramm verketten und die Ausgabe von Effekten zusammensetzen oder mischen.

Ein Direct2D-Effekt führt eine Bildverarbeitungsaufgabe aus, z. B. ändern der Helligkeit, Entsättigen eines Bilds oder Erstellen eines Schattens. Effekte können null oder mehr Eingabebilder akzeptieren, mehrere Eigenschaften verfügbar machen, die ihren Betrieb steuern, und ein einzelnes Ausgabebild generieren.

Jeder Effekt erstellt ein internes Transformationsdiagramm, das aus einzelnen Transformationen besteht. Jede Transformation stellt einen einzelnen Bildvorgang dar. Der Hauptzweck einer Transformation ist das Aufnehmen der Shader, die für jedes Ausgabepixel ausgeführt werden. Diese Shader können Pixel-Shader, Vertex-Shader, die Blendphase einer GPU und Compute-Shader enthalten.

Sowohl die integrierten Direct2D-Effekte als auch die benutzerdefinierten Effekte, die Sie mit der API für benutzerdefinierte Effekte vornehmen können, funktionieren auf diese Weise.

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

Sie können Effekte auf jede Bitmap anwenden, z. B.: Bilder, die von der Windows Imaging Component (WIC)geladen werden, Primitive, die von Direct2Dgezeichnet werden, Text aus DirectWriteoder Szenen, die von Direct3Dgerendert werden.

Mit Direct2D-Effekten können Sie eigene Effekte schreiben, die Sie für Ihre Anwendungen verwenden können. Mit einem benutzerdefinierten Effektframework können Sie GPU-Features wie Pixel-Shader, Vertex-Shader und die Mischungseinheit verwenden. Sie können auch andere integrierte oder benutzerdefinierte Effekte in Ihren benutzerdefinierten Effekt einschließen. Das Framework zum Erstellen von benutzerdefinierten Effekten ist dasselbe, das zum Erstellen der integrierten Effekte von Direct2Dverwendet wurde. Die Direct2D-Effektautor-API bietet eine Reihe von Schnittstellen zum Erstellen und Registrieren von Effekten.

Themen zu weiteren Effekten

Im weiteren Verlauf dieses Themas werden die Grundlagen von Direct2D-Effekten erläutert, z. B. das Anwenden eines Effekts auf ein Bild. Die folgende Tabelle enthält Links zu weiteren Themen zu Effekten.

Thema BESCHREIBUNG
Effektshader-Verknüpfung
Direct2D verwendet eine Optimierung namens Effekt-Shaderverknüpfung, die mehrere Effektdiagrammrenderingdurchläufe in einem einzelnen Durchlauf kombiniert.
Benutzerdefinierte Effekte
Hier erfahren Sie, wie Sie eigene benutzerdefinierte Effekte mit hlsl-Standardeffekten schreiben.
Laden eines Bilds in Direct2D Effects mit filePicker
Zeigt, wie sie den Windows::Storage::P schlüssels::FileOpenPicker verwenden, um ein Bild in Direct2D-Effekte zu laden.
Speichern von Direct2D-Inhalten in einer Bilddatei
In diesem Thema wird gezeigt, wie Sie IWICImageEncoder verwenden, um Inhalte in Form eines ID2D1Image in einer codierten Bilddatei wie JPEG zu speichern.
Anwenden von Effekten auf Primitive
In diesem Thema wird gezeigt, wie Sie eine Reihe von Effekten auf Direct2D und DirectWrite Primitive anwenden.
Steuern von Genauigkeit und numerischem Clipping in Effektdiagrammen
Anwendungen, die Effekte mit Direct2D rendern, müssen darauf achten, das gewünschte Maß an Qualität und Vorhersagbarkeit in Bezug auf die numerische Genauigkeit zu erreichen.

Anwenden eines Effekts auf ein Bild

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

Hinweis

In diesem Beispiel wird davon ausgegangen, dass Sie bereits id2D1DeviceContext- und IWICBitmapSource-Objekte erstellt haben. Weitere Informationen zum Erstellen dieser Objekte finden Sie unter Laden eines Bilds in Direct2D-Effekte mit filePicker und Geräten und Gerätekontexten.

  1. Deklarieren Sie eine ID2D1Effect-Variable, und erstellen Sie dann mithilfe der ID2DDeviceContext::CreateEffect-Methode einen Bitmap-Quelleffekt.

        ComPtr<ID2D1Effect> bitmapSourceEffect;
    
        DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1BitmapSource, &bitmapSourceEffect));
    
  2. Legen Sie die BitmapSource-Eigenschaft mit id2D1Effect::SetValueauf die WIC-Bitmapquelle fest.

            DX::ThrowIfFailed(m_bitmapSourceEffect->SetValue(D2D1_BITMAPSOURCE_PROP_WIC_BITMAP_SOURCE, m_wicBitmapSource.Get()));
    
  3. Deklarieren Sie eine VARIABLE ID2D1Effect, und erstellen Sie dann den Blureffekt "gaussian".

        ComPtr<ID2D1Effect> gaussianBlurEffect;
    
        DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1GaussianBlur, &gaussianBlurEffect));
    
  4. Legen Sie die Eingabe fest, um das Bild vom Bitmapquelleffekt zu empfangen. Legen Sie die Weichzeichnermenge für die SetValue-Methode und die Standardabweichungseigenschaft 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 DrawImage-Methode muss wie andere Direct2D-Rendervorgänge zwischen den Aufrufen ID2DDeviceContext::BeginDraw und EndDraw aufgerufen werden. DrawImage kann ein Bild oder die Ausgabe eines Effekts aufnehmen und auf der Zieloberfläche rendern.

Räumliche Transformationen

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

Hinweis

Der Anisotropiemodus generiert bei der Skalierung Mipmaps. Wenn Sie jedoch die Cached-Eigenschaft für die Effekte, die für die Transformation eingegeben werden, auf TRUE festlegen, werden die Mipmaps nicht jedes Mal für ausreichend kleine Bilder generiert.

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

Durch diese Verwendung des 2D-affinen Transformationseffekts wird die Bitmap gegen den Uhrzeigersinn leicht gedreht.

Vorher
2D-affiner Effekt vor dem Bild.
Danach
2D-affiner Effekt nach dem Bild.

Zusammenschalten von Bildern

Einige Effekte akzeptieren mehrere Eingaben und zusammengesetzt sie in einem resultierenden Bild.

Die integrierten zusammengesetzten und arithmetischen Verbundeffekte bieten verschiedene Modi. Weitere Informationen finden Sie im Thema zusammengesetzte Effekte. Der Blend-Effekt verfügt über eine Vielzahl 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 zusammengesetzte Effekt kombiniert Bilder auf verschiedene Weise gemäß dem von Ihnen angegebenen Modus.

Pixelanpassungen

Es gibt einige integrierte Direct2D-Effekte, mit denen Sie die Pixeldaten ändern können. Beispielsweise kann der Farbmatrixeffekt verwendet werden, um die Farbe eines Bilds zu ä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 übernimmt das Bild und ändert die Farbe, wie in den Beispielbildern hier gezeigt.

Vorher
Farbmatrixeffekt vor dem Bild.
Danach
Farbmatrixeffekt nach dem Bild.

Weitere Informationen finden Sie im Abschnitt Integrierte Farbeffekte.

Erstellen von Effektdiagrammen

Sie können Effekte verketten, um Bilder zu transformieren. Beispielsweise wendet der Code hier einen Schatten und eine 2D-Transformation an und kombiniert dann die Ergebnisse.

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

Im Folgenden wird das Ergebnis aufgeführt:

Schatteneffektausgabe.

Effekte verwenden 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 abzurufen, oder die SetInputEffect-Methode verwenden, die die Ausgabe für Sie konvertiert. In den meisten Fällen besteht ein Effektdiagramm aus direkt verketteten ID2D1Effect-Objekten, wodurch es einfach ist, mehrere Effekte auf ein Bild anzuwenden, um überzeugende Visuals zu erstellen.

Weitere Informationen finden Sie unter Anwenden von Effekten auf Primitive.

Beispiel für grundlegende Direct2D-Bildeffekte

Integrierte Effekte