Übersicht über Durchlässigkeitsmasken

In diesem Thema wird beschrieben, wie Bitmaps und Pinsel verwendet werden, um Deckkraftmasken zu definieren. Der Abschnitt ist wie folgt gegliedert.

Voraussetzungen

In dieser Übersicht wird davon ausgegangen, dass Sie mit grundlegenden Direct2D-Zeichnungsvorgängen vertraut sind, wie in der exemplarischen Vorgehensweise Erstellen einer einfachen Direct2D-Anwendung beschrieben. Sie sollten auch mit den verschiedenen Typen von Pinseln vertraut sein, wie in der Übersicht über Pinselbeschrieben.

Was ist eine Deckkraftmaske?

Eine Deckkraftmaske ist eine Maske, die von einem Pinsel oder einer Bitmap beschrieben wird und 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 in das endgültige Zielziel gemischt werden. Die transparenten Teile der Maske geben die Bereiche an, in denen das zugrunde liegende Bild ausgeblendet ist, während die nicht transparenten 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 ID2D1BitmapBrushund 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 ein ID2D1Layer-Objekt, 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. Weitere 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 ID2D1Bitmapdefiniert 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 der Anwendung der Deckkraftmaske (eine ID2D1Bitmap mit einem Bild einer Blume) auf einen ID2D1BitmapBrush mit einem Bild einer Farnanlage. Das resultierende Bild ist eine Bitmap einer Anlage, die auf die Blumenform abgeschnitten ist.

Diagramm einer Als Deckkraftmaske verwendeten Bitmap für ein Bild einer Farnanlage

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 Ausgabe, die erzeugt wird. Beachten Sie, dass die Farbinformationen in der Bitmap keine Auswirkungen auf die Deckkraftmaske haben, obwohl der nicht transparente Teil der Bitmap schwarz angezeigt wird. werden nur die Deckkraftinformationen jedes Pixels in der Bitmap verwendet. Die vollständig deckenden Pixel in dieser Bitmap wurden nur zur Veranschaulichung schwarz farbig dargestellt.

Abbildung der Maske für Die Maske der Blumebitmap

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 verwendet, der ein Bild eines Farns enthält, aber Sie können stattdessen einen ID2D1SolidColorBrush, ID2D1LinearGradientBrushoder ID2D1RadialGradientBrush verwenden. Die folgende Abbildung zeigt die Ausgabe, die erzeugt wird.

Abbildung der vom Bitmappinsel verwendeten Bitmap

            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 wurden, 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 D2D1 _ OPACITY _ MASK _ CONTENT nicht mehr erforderlich. Siehe die ID2D1DeviceContext::FillOpacityMask-Methode, die über keinen D2D1 _ OPACITY _ MASK _ CONTENT-Parameter verfügt.

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 Typ des Inhalts innerhalb der Deckkraftmaske (D2D1 _ OPACITY _ MASK CONTENT _ _ GRAPHICS) und den zu zeichnenden Bereich. Die folgende Abbildung zeigt die Ausgabe, die erzeugt wird.

Abbildung des Fernanlagenbilds mit angewendeter 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 in diesem Beispiel ausgelassen.

Verwenden eines Pinsels als Deckkraftmaske mit der FillGeometry-Methode

Im vorherigen Abschnitt wurde die Verwendung einer ID2D1Bitmap als Deckkraftmaske beschrieben. Direct2D stellt auch die ID2D1RenderTarget::FillGeometry-Methode bereit, mit der Sie optional einen Pinsel als Deckkraftmaske angeben können, wenn Sie eine ID2D1Geometryausfüllen. Dadurch können Sie Deckkraftmasken aus Farbverläufen (mit ID2D1LinearGradientBrush oder ID2D1RadialGradientBrush)und Bitmaps (mit ID2D1Bitmap) erstellen.

Die FillGeometry-Methode nimmt drei Parameter an:

In den folgenden Abschnitten wird beschrieben, wie Id2D1LinearGradientBrush- und ID2D1RadialGradientBrush-Objekte 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 Linien gefüllt ist.

Diagramm einer Blumenbitmap mit angewendeter linearer Farbverlaufspinsel

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

  1. Definieren Sie den zu maskierten Inhalt. Im folgenden Beispiel wird ein ID2D1BitmapBrush ,m _ pLinearFadeFlowersBitmap erstellt. Der Extendermodus x- und y- für m _ pLinearFadeFlowersBitmap ist auf D2D1 _ EXTEND MODE _ _ CLAMP festgelegt, sodass er mit einer Deckkraftmaske durch die 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 deckendem Schwarz an Position 0 bis zu vollständig transparentem Weiß an Position 1 ausblendet.

                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) zu verwenden.
            m_pRenderTarget->FillGeometry(
                m_pRectGeo, 
                m_pLinearFadeFlowersBitmapBrush, 
                m_pLinearGradientBrush
                );

Code wurde in diesem Beispiel ausgelassen.

Verwenden eines radialen Farbverlaufspinsels als Deckkraftmaske

Das folgende Diagramm zeigt den visuellen Effekt der Anwendung eines radialen Farbverlaufspinsels auf ein Rechteck, das mit einer Bitmap von Blättern gefüllt ist.

Diagramm einer Blätternbitmap mit angewendeten radialen Farbverlaufspinsel

Im ersten Beispiel wird ein ID2D1BitmapBrusherstellt, m _ pRadialFadeFlowersBitmapBrush. Damit sie mit einer Deckkraftmaske von der FillGeometry-Methode verwendet werden kann, werden der Extendmodus x- und y- für m _ pRadialFadeFlowersBitmapBrush auf D2D1 _ EXTEND MODE _ _ CLAMPfestgelegt.

            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 Pinsel für den radialen Farbverlauf 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 in diesem Beispiel ausgelassen.

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 unter Übersicht über Ebenen.

Übersicht über Pinsel

Übersicht über Ebenen