Übersicht über Durchlässigkeitsmasken

In diesem Thema wird beschrieben, wie Bitmaps und Pinsel zum Definieren von Deckkraftmasken verwendet werden. Der Abschnitt ist wie folgt gegliedert.

Voraussetzungen

In dieser Übersicht wird davon ausgegangen, dass Sie mit grundlegenden Direct2D-Zeichnungsvorgängen vertraut sind, wie unter Erstellen einer einfachen Direct2D-Anwendung beschrieben. Sie sollten auch mit den verschiedenen Pinseltypen vertraut sein, wie in der Übersicht über Pinsel beschrieben.

Was ist eine Deckkraftmaske?

Eine Deckkraftmaske ist eine durch einen Pinsel oder eine Bitmap beschriebene Maske, die auf ein anderes Objekt angewendet wird, um dieses Objekt teilweise oder vollständig transparent zu machen. Eine Deckkraftmaske verwendet Alphakanalinformationen, um anzugeben, wie die Quellpixel des Objekts mit dem endgültigen Zielziel zusammengeführt werden. Die transparenten Teile der Maske geben die Bereiche an, in denen das zugrunde liegende Bild ausgeblendet ist, während die undurchsichtigen Teile der Maske angeben, wo das maskierte Objekt sichtbar ist.

Es gibt mehrere Möglichkeiten, eine Deckkraftmaske anzuwenden:

  • Verwenden Sie die ID2D1RenderTarget::FillOpacityMask-Methode . Die FillOpacityMask-Methode zeichnet einen rechteckigen Bereich eines Renderziels und wendet dann eine Deckkraftmaske an, die durch eine Bitmap definiert wird. Verwenden Sie diese Methode, wenn Ihre Deckkraftmaske eine Bitmap ist und Sie einen rechteckigen Bereich ausfüllen möchten.
  • Verwenden Sie die ID2D1RenderTarget::FillGeometry-Methode . Die FillGeometry-Methode zeichnet das Innere der Geometrie mit dem angegebenen ID2D1BitmapBrush und wendet dann eine Deckkraftmaske an, die durch einen Pinsel definiert wird. Verwenden Sie diese Methode, wenn Sie eine Deckkraftmaske auf eine Geometrie anwenden oder einen Pinsel als Deckkraftmaske verwenden möchten.
  • Verwenden Sie einen ID2D1Layer , um eine Deckkraftmaske anzuwenden. Verwenden Sie diesen Ansatz, wenn Sie eine Deckkraftmaske auf eine Gruppe von Zeichnungsinhalten anwenden möchten, nicht nur auf eine einzelne Form oder ein einzelnes Bild. Ausführliche Informationen finden Sie in der Übersicht über Ebenen.

Verwenden einer Bitmap als Deckkraftmaske mit der FillOpacityMask-Methode

Die FillOpacityMask-Methode zeichnet einen rechteckigen Bereich eines Renderziels und wendet dann eine Deckkraftmaske an, die durch eine ID2D1Bitmap definiert wird. Verwenden Sie diese Methode, wenn Sie über eine Bitmap verfügen, die Sie als Deckkraftmaske für einen rechteckigen Bereich verwenden möchten.

Das folgende Diagramm zeigt einen Effekt des Anwendens der Deckkraftmaske (eine ID2D1Bitmap mit einem Bild einer Blume) auf einen ID2D1BitmapBrush mit einem Bild einer Farnpflanze. Das resultierende Bild ist eine Bitmap einer Pflanze, die an die Blumenform gekappt ist.

Diagramm einer Als Deckkraftmaske verwendeten Blumen-Bitmap auf einem Bild einer Farnpflanze

Die folgenden Codebeispiele zeigen, wie dies erreicht wird.

Im ersten Beispiel wird die folgende Bitmap m_pBitmapMask zur Verwendung als Bitmapmaske geladen. Die folgende Abbildung zeigt die erzeugte Ausgabe. Beachten Sie, dass der undurchsichtige Teil der Bitmap zwar schwarz angezeigt wird, die Farbinformationen in der Bitmap jedoch keine Auswirkungen auf die Deckkraftmaske haben. es werden nur die Deckkraftinformationen der einzelnen Pixel in der Bitmap verwendet. Die vollständig undurchsichtigen Pixel in dieser Bitmap wurden nur zu Veranschaulichungszwecken schwarz gefärbt.

Abbildung der Bitmapmaske für Blumen

In diesem Beispiel wird die ID2D1Bitmap von der Hilfsmethode LoadResourceBitmap geladen, die an anderer Stelle im Beispiel definiert ist.

            if (SUCCEEDED(hr))
            {
                hr = LoadResourceBitmap(
                    m_pRenderTarget,
                    m_pWICFactory,
                    L"BitmapMask",
                    L"Image",
                    &m_pBitmapMask
                    );
            }

Im nächsten Beispiel wird der Pinsel m_pFernBitmapBrush definiert, auf den die Deckkraftmaske angewendet wird. In diesem Beispiel wird ein ID2D1BitmapBrush-Objekt verwendet, das ein Bild eines Farns enthält. Sie können jedoch stattdessen id2D1SolidColorBrush, ID2D1LinearGradientBrush oder ID2D1RadialGradientBrush verwenden. Die folgende Abbildung zeigt die erzeugte Ausgabe.

Abbildung der Bitmap, die vom Bitmappinsel verwendet wird

            if (SUCCEEDED(hr))
            {
                D2D1_BITMAP_BRUSH_PROPERTIES propertiesXClampYClamp = 
                    D2D1::BitmapBrushProperties(
                    D2D1_EXTEND_MODE_CLAMP,
                    D2D1_EXTEND_MODE_CLAMP,
                    D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR
                    );
                hr = m_pRenderTarget->CreateBitmapBrush(
                    m_pFernBitmap,
                    propertiesXClampYClamp,
                    &m_pFernBitmapBrush
                    );


            }

Nachdem die Deckkraftmaske und der Pinsel definiert sind, können Sie die FillOpacityMask-Methode in der Renderingmethode Ihrer Anwendung verwenden. Wenn Sie die FillOpacityMask-Methode aufrufen, müssen Sie den Typ der verwendeten Deckkraftmaske angeben: D2D1_OPACITY_MASK_CONTENT_GRAPHICS, D2D1_OPACITY_MASK_CONTENT_TEXT_NATURAL und D2D1_OPACITY_MASK_CONTENT_TEXT_GDI_COMPATIBLE. Die Bedeutungen dieser drei Typen finden Sie unter D2D1_OPACITY_MASK_CONTENT.

Hinweis

Ab Windows 8 ist die D2D1_OPACITY_MASK_CONTENT nicht erforderlich. Siehe die ID2D1DeviceContext:FillOpacityMask-Methode , die keinen D2D1_OPACITY_MASK_CONTENT-Parameter aufweist.

 

Im nächsten Beispiel wird der Antialiasingmodus des Renderziels auf D2D1_ANTIALIAS_MODE_ALIASED festgelegt, damit die Deckkraftmaske ordnungsgemäß funktioniert. Anschließend ruft sie die FillOpacityMask-Methode auf und übergibt ihr die Deckkraftmaske (m_pBitmapMask), den Pinsel, auf den die Deckkraftmaske angewendet wird (m_pFernBitmapBrush), den Inhaltstyp innerhalb der Deckkraftmaske (D2D1_OPACITY_MASK_CONTENT_GRAPHICS) und den zu zeichnenden Bereich. Die folgende Abbildung zeigt die erzeugte Ausgabe.

Abbildung des Farnpflanzenbilds mit aufgetragener Deckkraftmaske

        D2D1_RECT_F rcBrushRect = D2D1::RectF(5, 5, 155, 155);


        // D2D1_ANTIALIAS_MODE_ALIASED must be set for FillOpacityMask to function properly
        m_pRenderTarget->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
        m_pRenderTarget->FillOpacityMask(
            m_pBitmapMask,
            m_pFernBitmapBrush,
            D2D1_OPACITY_MASK_CONTENT_GRAPHICS,
            &rcBrushRect
            );
        m_pRenderTarget->SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);

Code wurde aus diesem Beispiel weggelassen.

Verwenden eines Pinsels als Deckkraftmaske mit der FillGeometry-Methode

Im vorherigen Abschnitt wurde beschrieben, wie eine ID2D1Bitmap als Deckkraftmaske verwendet wird. Direct2D bietet auch die ID2D1RenderTarget::FillGeometry-Methode , mit der Sie den Pinsel optional als Deckkraftmaske angeben können, wenn Sie eine ID2D1Geometry füllen. Dadurch können Sie Deckkraftmasken aus Farbverläufen (mit ID2D1LinearGradientBrush oder ID2D1RadialGradientBrush) und Bitmaps (mit ID2D1Bitmap) erstellen.

Die FillGeometry-Methode benötigt drei Parameter:

In den folgenden Abschnitten wird beschrieben, wie Die Objekte ID2D1LinearGradientBrush und ID2D1RadialGradientBrush als Deckkraftmasken verwendet werden.

Verwenden eines linearen Farbverlaufspinsels als Deckkraftmaske

Das folgende Diagramm zeigt die Auswirkung des Anwendens eines linearen Farbverlaufspinsels auf ein Rechteck, das mit einer Bitmap von Blumen gefüllt ist.

Diagramm einer Blumen-Bitmap mit angewendetem Pinsel für linearen Farbverlauf

In den folgenden Schritten wird beschrieben, wie Dieser Effekt neu erstellt wird.

  1. Definieren Sie den zu maskierenden Inhalt. Im folgenden Beispiel wird eine ID2D1BitmapBrush-m_pLinearFadeFlowersBitmap erstellt. Der Erweiterungsmodus x- und y- für m_pLinearFadeFlowersBitmap sind auf D2D1_EXTEND_MODE_CLAMP festgelegt, sodass er mit einer Deckkraftmaske von der FillGeometry-Methode verwendet werden kann.

    if (SUCCEEDED(hr))
    {
        // Create the bitmap to be used by the bitmap brush.
        hr = LoadResourceBitmap(
            m_pRenderTarget,
            m_pWICFactory,
            L"LinearFadeFlowers",
            L"Image",
            &m_pLinearFadeFlowersBitmap
            );
    }
    
    if (SUCCEEDED(hr))
        {
            D2D1_BITMAP_BRUSH_PROPERTIES propertiesXClampYClamp = 
                D2D1::BitmapBrushProperties(
                D2D1_EXTEND_MODE_CLAMP,
                D2D1_EXTEND_MODE_CLAMP,
                D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR
                );
    
    C++
                    if (SUCCEEDED(hr))
                    {
                        hr = m_pRenderTarget->CreateBitmapBrush(
                            m_pLinearFadeFlowersBitmap,
                            propertiesXClampYClamp,
                            &m_pLinearFadeFlowersBitmapBrush
                            );
                    }
    C++
                }
  2. Definieren Sie die Deckkraftmaske. Im nächsten Codebeispiel wird ein diagonaler linearer Farbverlaufspinsel (m_pLinearGradientBrush) erstellt, der von vollständig undurchsichtigem Schwarz an Position 0 auf vollständig transparentes Weiß an Position 1 verblasst.

                if (SUCCEEDED(hr))
                {
                    ID2D1GradientStopCollection *pGradientStops = NULL;

                    static const D2D1_GRADIENT_STOP gradientStops[] =
                    {
                        {   0.f,  D2D1::ColorF(D2D1::ColorF::Black, 1.0f)  },
                        {   1.f,  D2D1::ColorF(D2D1::ColorF::White, 0.0f)  },
                    };

                    hr = m_pRenderTarget->CreateGradientStopCollection(
                        gradientStops,
                        2,
                        &pGradientStops);


                    if (SUCCEEDED(hr))
                    {
                        hr = m_pRenderTarget->CreateLinearGradientBrush(
                            D2D1::LinearGradientBrushProperties(
                                D2D1::Point2F(0, 0),
                                D2D1::Point2F(150, 150)),
                            pGradientStops,
                            &m_pLinearGradientBrush);
                    }

    
                pGradientStops->Release();
                }
  1. Verwenden Sie die FillGeometry-Methode . Im letzten Beispiel wird die FillGeometry-Methode für den Inhaltspinsel verwendet, um eine ID2D1RectangleGeometry (m_pRectGeo) mit einem ID2D1BitmapBrush (m_pLinearFadeFlowersBitmap) zu füllen und eine Deckkraftmaske (m_pLinearGradientBrush) an.
            m_pRenderTarget->FillGeometry(
                m_pRectGeo, 
                m_pLinearFadeFlowersBitmapBrush, 
                m_pLinearGradientBrush
                );

Code wurde aus diesem Beispiel weggelassen.

Verwenden eines Radialverlaufspinsels als Deckkraftmaske

Das folgende Diagramm zeigt den visuellen Effekt des Anwendens eines radialen Farbverlaufspinsels auf ein Rechteck, das mit einer Bitmap aus Laub gefüllt ist.

Diagramm einer laubförmigen Bitmap mit angewendetem Radialverlaufspinsel

Im ersten Beispiel wird ein ID2D1BitmapBrushm_pRadialFadeFlowersBitmapBrush erstellt. Damit es mit einer Deckkraftmaske von der FillGeometry-Methode verwendet werden kann, sind die Verlängerungsmodus x- und y- für m_pRadialFadeFlowersBitmapBrush auf D2D1_EXTEND_MODE_CLAMP festgelegt.

            if (SUCCEEDED(hr))
            {
                // Create the bitmap to be used by the bitmap brush.
                hr = LoadResourceBitmap(
                    m_pRenderTarget,
                    m_pWICFactory,
                    L"RadialFadeFlowers",
                    L"Image",
                    &m_pRadialFadeFlowersBitmap
                    );
            }


            if (SUCCEEDED(hr))
            {
                D2D1_BITMAP_BRUSH_PROPERTIES propertiesXClampYClamp = 
                    D2D1::BitmapBrushProperties(
                    D2D1_EXTEND_MODE_CLAMP,
                    D2D1_EXTEND_MODE_CLAMP,
                    D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR
                    );
C++
                if (SUCCEEDED(hr))
                {
                    hr = m_pRenderTarget->CreateBitmapBrush(
                        m_pLinearFadeFlowersBitmap,
                        propertiesXClampYClamp,
                        &m_pLinearFadeFlowersBitmapBrush
                        );
                }
C++
            }

Im nächsten Beispiel wird der radiale Farbverlaufspinsel definiert, der als Deckkraftmaske verwendet wird.

            if (SUCCEEDED(hr))
            {
                ID2D1GradientStopCollection *pGradientStops = NULL;

                static const D2D1_GRADIENT_STOP gradientStops[] =
                {
                    {   0.f,  D2D1::ColorF(D2D1::ColorF::Black, 1.0f)  },
                    {   1.f,  D2D1::ColorF(D2D1::ColorF::White, 0.0f)  },
                };

                hr = m_pRenderTarget->CreateGradientStopCollection(
                    gradientStops,
                    2,
                    &pGradientStops);




                if (SUCCEEDED(hr))
                {
                    hr = m_pRenderTarget->CreateRadialGradientBrush(
                        D2D1::RadialGradientBrushProperties(
                            D2D1::Point2F(75, 75),
                            D2D1::Point2F(0, 0),
                            75,
                            75),
                        pGradientStops,
                        &m_pRadialGradientBrush);
                }
                pGradientStops->Release();
            }

Im letzten Codebeispiel werden id2D1BitmapBrush (m_pRadialFadeFlowersBitmapBrush) und die Deckkraftmaske (m_pRadialGradientBrush) verwendet, um eine ID2D1RectangleGeometry (m_pRectGeo) auszufüllen.

        m_pRenderTarget->FillGeometry(
            m_pRectGeo,
            m_pRadialFadeFlowersBitmapBrush, 
            m_pRadialGradientBrush
            );

Code wurde aus diesem Beispiel weggelassen.

Anwenden einer Deckkraftmaske auf eine Ebene

Wenn Sie PushLayer aufrufen, um einen ID2D1Layer auf ein Renderziel zu pushen, können Sie die D2D1_LAYER_PARAMETERS Struktur verwenden, um einen Pinsel als Deckkraftmaske anzuwenden. Im folgenden Codebeispiel wird ein ID2D1RadialGradientBrush als Deckkraftmaske verwendet.

HRESULT DemoApp::RenderWithLayerWithOpacityMask(ID2D1RenderTarget *pRT)
{   

    HRESULT hr = S_OK;

    // Create a layer.
    ID2D1Layer *pLayer = NULL;
    hr = pRT->CreateLayer(NULL, &pLayer);

    if (SUCCEEDED(hr))
    {
        pRT->SetTransform(D2D1::Matrix3x2F::Translation(300, 250));

        // Push the layer with the content bounds.
        pRT->PushLayer(
            D2D1::LayerParameters(
                D2D1::InfiniteRect(),
                NULL,
                D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
                D2D1::IdentityMatrix(),
                1.0,
                m_pRadialGradientBrush,
                D2D1_LAYER_OPTIONS_NONE),
            pLayer
            );

        pRT->DrawBitmap(m_pBambooBitmap, D2D1::RectF(0, 0, 190, 127));

        pRT->FillRectangle(
            D2D1::RectF(25.f, 25.f, 50.f, 50.f), 
            m_pSolidColorBrush
            );
        pRT->FillRectangle(
            D2D1::RectF(50.f, 50.f, 75.f, 75.f),
            m_pSolidColorBrush
            ); 
        pRT->FillRectangle(
            D2D1::RectF(75.f, 75.f, 100.f, 100.f),
            m_pSolidColorBrush
            );    
 
        pRT->PopLayer();
    }
    SafeRelease(&pLayer);
   
    return hr;
    
}

Weitere Informationen zur Verwendung von Ebenen finden Sie in der Übersicht über Ebenen.

Übersicht über Pinsel

Übersicht über Ebenen