Läs på engelska

Dela via


Översikt över ogenomskinlighetsmasker

Det här avsnittet beskriver hur du använder bitmappar och penslar för att definiera ogenomskinliga masker. Den innehåller följande avsnitt.

Förutsättningar

Den här översikten förutsätter att du är bekant med grundläggande Direct2D-ritningsåtgärder enligt beskrivningen i Skapa ett enkelt Direct2D-program genomgång. Du bör också känna till de olika typerna av penslar enligt beskrivningen i Brushes Overview.

Vad är en ogenomskinlig mask?

En ogenomskinlig mask är en mask, som beskrivs av en pensel eller bitmapp, som tillämpas på ett annat objekt för att göra objektet delvis eller helt transparent. En ogenomskinlig mask använder alfakanalinformation för att ange hur objektets källpixlar ska blandas i det slutliga målmålet. De transparenta delarna av masken anger de områden där den underliggande bilden är dold, medan de ogenomskinliga delarna av masken anger var det maskerade objektet är synligt.

Det finns flera sätt att använda en ogenomskinlig mask:

  • Använd metoden ID2D1RenderTarget::FillOpacityMask. Metoden FillOpacityMask målar upp en rektangulär region för ett återgivningsmål och tillämpar sedan en opacitetsmask som definieras av en bitmapp. Använd den här metoden när din opacitetsmask är en bitmapp och du vill fylla en rektangulär region.
  • Använd metoden ID2D1RenderTarget::FillGeometry. Metoden FillGeometry målar geometrins inre med angiven ID2D1BitmapBrushoch tillämpar sedan en ogenomskinlighetsmask som definieras av en pensel. Använd den här metoden när du vill använda en opacitetsmask på en geometri eller om du vill använda en pensel som en ogenomskinlig mask.
  • Använd en ID2D1Layer- för att använda en ogenomskinlig mask. Använd den här metoden när du vill använda en ogenomskinlig mask på en grupp med ritningsinnehåll, inte bara en enda form eller bild. Mer information finns i översikten över lager.

Använda en bitmapp som en opacitetsmask med metoden FillOpacityMask

Metoden FillOpacityMask målar en rektangulär region för ett återgivningsmål och tillämpar sedan en ogenomskinlighetsmask som definieras av en ID2D1Bitmap. Använd den här metoden när du har en bitmapp som du vill använda som en ogenomskinlig mask för en rektangulär region.

Följande diagram visar en effekt av att tillämpa opacitetsmasken (en ID2D1Bitmap med en bild av en blomma) på en ID2D1BitmapBrush med en bild av en ormbunkeväxt. Den resulterande bilden är en bitmapp av en växt som klippts till blomformen.

diagram över en blombitkarta som används som en ogenomskinlig mask på en bild av en ormbunkeväxt

Följande kodexempel visar hur detta går till.

I det första exemplet läses följande bitmapp, m_pBitmapMask, in för användning som en bitmappsmask. Följande bild visar det resultat som produceras. Observera att även om den ogenomskinliga delen av bitmappen verkar svart, har färginformationen i bitmappen ingen effekt på ogenomskinlighetsmasken. endast ogenomskinlighetsinformationen för varje pixel i bitmappen används. De helt ogenomskinliga bildpunkterna i den här bitmappen har endast färgats svart i illustrativa syften.

bild av blommans bitmappsmask

I det här exemplet läses ID2D1Bitmap in av en hjälpmetod, LoadResourceBitmap, som definieras någon annanstans i exemplet.

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

I nästa exempel definieras penseln, m_pFernBitmapBrush, som opacitetsmasken tillämpas på. I det här exemplet används en ID2D1BitmapBrush- som innehåller en bild av en ormbunke, men du kan använda en ID2D1SolidColorBrush, ID2D1LinearGradientBrusheller ID2D1RadialGradientBrush i stället. Följande bild visar resultaten som skapas.

bild av bitmappen som används av bitmappsborsten

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


            }

Nu när opacitetsmasken och penseln har definierats kan du använda metoden FillOpacityMask i programmets återgivningsmetod. När du anropar metoden FillOpacityMask måste du ange vilken typ av opacitetsmask du använder: D2D1_OPACITY_MASK_CONTENT_GRAPHICS, D2D1_OPACITY_MASK_CONTENT_TEXT_NATURALoch D2D1_OPACITY_MASK_CONTENT_TEXT_GDI_COMPATIBLE. För innebörden av dessa tre typer, se D2D1_OPACITY_MASK_CONTENT.

Anteckning

Från och med Windows 8 krävs inte D2D1_OPACITY_MASK_CONTENT. Se metoden ID2D1DeviceContext::FillOpacityMask, som inte har någon D2D1_OPACITY_MASK_CONTENT parameter.

 

I nästa exempel anges återgivningsmålets antialiaseringsläge till D2D1_ANTIALIAS_MODE_ALIASED så att opacitetsmasken fungerar korrekt. Den anropar sedan metoden FillOpacityMask och skickar den ogenomskinlighetsmasken (m_pBitmapMask), penseln som opacitetsmasken tillämpas på (m_pFernBitmapBrush), typen av innehåll inuti opacitetsmasken (D2D1_OPACITY_MASK_CONTENT_GRAPHICS) och det område som ska målas. Följande illustration visar de resultat som produceras.

illustration av ormbunke med en opacitetsmask applicerad

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

Koden har utelämnats från det här exemplet.

Använda en pensel som en ogenomskinlig mask med metoden FillGeometry

I föregående avsnitt beskrivs hur du använder en ID2D1Bitmap- som en ogenomskinlig mask. Direct2D innehåller också metoden ID2D1RenderTarget::FillGeometry, som låter dig specificera en pensel som en opacitetsmask när du fyller en ID2D1Geometry. På så sätt kan du skapa ogenomskinliga masker från toningar (med hjälp av ID2D1LinearGradientBrush eller ID2D1RadialGradientBrush) och bitmappar (med ID2D1Bitmap).

Metoden FillGeometry tar tre parametrar:

I följande avsnitt beskrivs hur du använder ID2D1LinearGradientBrush och ID2D1RadialGradientBrush objekt som ogenomskinlighetsmasker.

Använd en linjär övertoningspensel som en opacitetsmask

Följande diagrammet visar effekten av att tillämpa en linjär färgövergång på en rektangel som är fylld med en bitmapp med blommor.

bild av en blomma bitmapp med en linjär gradientpensel tillämpad på

Stegen nedan beskriver hur du återskapar den här effekten.

  1. Definiera innehållet som ska maskeras. I följande exempel skapar man en ID2D1BitmapBrushoch m_pLinearFadeFlowersBitmap. "Utökningsläget x- och y- för m_pLinearFadeFlowersBitmap är inställda på D2D1_EXTEND_MODE_CLAMP så att det kan användas med en opacitetsmask av metoden FillGeometry."

    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. Definiera opacitetsmasken. I nästa kodexempel skapas en diagonal linjär toningspensel (m_pLinearGradientBrush) som tonar från helt opakt svart vid position 0 till helt transparent vitt vid position 1.

                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. Använd metoden FillGeometry. Det sista exemplet använder metoden FillGeometry till innehållsborsten för att fylla en ID2D1RectangleGeometry (m_pRectGeo) med en ID2D1BitmapBrush (m_pLinearFadeFlowersBitmap) och tillämpar en ogenomskinlig mask (m_pLinearGradientBrush).
            m_pRenderTarget->FillGeometry(
                m_pRectGeo, 
                m_pLinearFadeFlowersBitmapBrush, 
                m_pLinearGradientBrush
                );

Koden har utelämnats från det här exemplet.

Använd en radiell toningsborste som opacitetsmask

Följande figur visar den visuella effekten av att tillämpa en radiell färgövergång på en rektangel som är fylld med ett bitmapmönster av lövverk.

diagram över en blad-bitmap med en radiell toningsborste applicerad

I det första exemplet skapas en ID2D1BitmapBrush, m_pRadialFadeFlowersBitmapBrush. Så att den kan användas med en opacitetsmask av metoden FillGeometry är x- och y-läget för m_pRadialFadeFlowersBitmapBrush inställda på D2D1_EXTEND_MODE_CLAMP.

            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++
            }

I nästa exempel definieras den radiella gradientpensel som ska användas som täthetsmask.

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

Det sista kodexemplet använder ID2D1BitmapBrush (m_pRadialFadeFlowersBitmapBrush) och opacitetsmasken (m_pRadialGradientBrush) för att fylla en ID2D1RectangleGeometry (m_pRectGeo).

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

Koden har utelämnats från det här exemplet.

Tillämpa en opacitetsmask på ett lager

När du anropar PushLayer för att skicka en ID2D1Layer till ett återgivningsmål kan du använda D2D1_LAYER_PARAMETERS struktur för att använda en pensel som en ogenomskinlig mask. I följande kodexempel används en ID2D1RadialGradientBrush som en opacitetsmask.

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;
    
}

För mer information om hur du använder lager, se Lageröversikt.

Penslar: en översikt

Översikt över lager