Gambaran Umum Masker Opasitas

Topik ini menjelaskan cara menggunakan bitmap dan kuas untuk menentukan masker opasitas. Ini berisi bagian berikut.

Prasyarat

Gambaran umum ini mengasumsikan bahwa Anda terbiasa dengan operasi gambar Direct2D dasar, seperti yang dijelaskan dalam panduan Membuat aplikasi Direct2D sederhana . Anda juga harus terbiasa dengan berbagai jenis kuas, seperti yang dijelaskan dalam Gambaran Umum Brush.

Apa itu Masker Opacity?

Masker opasitas adalah masker, yang dijelaskan oleh kuas atau bitmap, yang diterapkan ke objek lain untuk membuat objek itu sebagian atau benar-benar transparan. Masker opasitas menggunakan informasi saluran alfa untuk menentukan bagaimana piksel sumber objek digabungkan ke target tujuan akhir. Bagian transparan dari masker menunjukkan area di mana gambar yang mendasar disembunyikan, sedangkan bagian buram dari masker menunjukkan di mana objek bertopeng terlihat.

Ada beberapa cara untuk menerapkan masker opasitas:

  • Gunakan metode ID2D1RenderTarget::FillOpacityMask . Metode FillOpacityMask melukiskan wilayah persegi panjang dari target render dan kemudian menerapkan masker opasitas, yang ditentukan oleh bitmap. Gunakan metode ini ketika masker opasitas Anda adalah bitmap dan Anda ingin mengisi wilayah persegi panjang.
  • Gunakan metode ID2D1RenderTarget::FillGeometry . Metode FillGeometry melukis interior geometri dengan ID2D1BitmapBrush yang ditentukan, lalu menerapkan masker opasitas, yang ditentukan oleh kuas. Gunakan metode ini ketika Anda ingin menerapkan masker opasitas ke geometri atau Anda ingin menggunakan kuas sebagai masker opasitas.
  • Gunakan ID2D1Layer untuk menerapkan masker opasitas. Gunakan pendekatan ini saat Anda ingin menerapkan masker opasitas ke sekelompok konten gambar, bukan hanya satu bentuk atau gambar. Untuk detailnya, lihat Gambaran Umum Lapisan.

Gunakan Bitmap sebagai Masker Opacity dengan Metode FillOpacityMask

Metode FillOpacityMask melukiskan wilayah persegi panjang dari target render dan kemudian menerapkan masker opasitas, yang ditentukan oleh ID2D1Bitmap. Gunakan metode ini ketika Anda memiliki bitmap yang ingin Anda gunakan sebagai masker opasitas untuk wilayah persegi panjang.

Diagram berikut menunjukkan efek menerapkan masker opasitas ( ID2D1Bitmap dengan gambar bunga) ke ID2D1BitmapBrush dengan gambar tanaman pakis. Gambar yang dihasilkan adalah bitmap dari tanaman yang terpotong ke bentuk bunga.

diagram bitmap bunga yang digunakan sebagai masker opasitas pada gambar tanaman pakis

Contoh kode berikut menunjukkan bagaimana hal ini dicapai.

Contoh pertama memuat bitmap berikut, m_pBitmapMask, untuk digunakan sebagai masker bitmap. Ilustrasi berikut menunjukkan output yang dihasilkan. Perhatikan bahwa, meskipun bagian buram dari bitmap tampak hitam, informasi warna dalam bitmap tidak berpengaruh pada masker opasitas; hanya informasi opasitas setiap piksel dalam bitmap yang digunakan. Piksel yang sepenuhnya buram dalam bitmap ini telah berwarna hitam hanya untuk tujuan ilustrasi.

ilustrasi masker bitmap bunga

Dalam contoh ini, ID2D1Bitmap dimuat oleh metode pembantu, LoadResourceBitmap, yang ditentukan di tempat lain dalam sampel.

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

Contoh berikutnya mendefinisikan kuas, m_pFernBitmapBrush, tempat masker opasitas diterapkan. Contoh ini menggunakan ID2D1BitmapBrush yang berisi gambar pakis, tetapi Anda dapat menggunakan ID2D1SolidColorBrush, ID2D1LinearGradientBrush, atau ID2D1RadialGradientBrush sebagai gantinya. Ilustrasi berikut menunjukkan output yang dihasilkan.

ilustrasi bitmap yang digunakan oleh kuas 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
                    );


            }

Sekarang masker opasitas dan kuas ditentukan, Anda dapat menggunakan metode FillOpacityMask dalam metode penyajian aplikasi Anda. Saat Anda memanggil metode FillOpacityMask , Anda harus menentukan jenis masker opasitas yang Anda gunakan: D2D1_OPACITY_MASK_CONTENT_GRAPHICS, D2D1_OPACITY_MASK_CONTENT_TEXT_NATURAL, dan D2D1_OPACITY_MASK_CONTENT_TEXT_GDI_COMPATIBLE. Untuk arti ketiga jenis ini, lihat D2D1_OPACITY_MASK_CONTENT.

Catatan

Dimulai dengan Windows 8, D2D1_OPACITY_MASK_CONTENT tidak diperlukan. Lihat metode ID2D1DeviceContext::FillOpacityMask , yang tidak memiliki parameter D2D1_OPACITY_MASK_CONTENT .

 

Contoh berikutnya menetapkan mode antialias target render ke D2D1_ANTIALIAS_MODE_ALIASED sehingga masker opasitas akan berfungsi dengan baik. Kemudian memanggil metode FillOpacityMask dan meneruskannya masker opasitas (m_pBitmapMask), kuas tempat masker opasitas diterapkan (m_pFernBitmapBrush), jenis konten di dalam masker opasitas (D2D1_OPACITY_MASK_CONTENT_GRAPHICS), dan area untuk dicat. Ilustrasi berikut menunjukkan output yang dihasilkan.

ilustrasi gambar tanaman pakis dengan masker opasitas diterapkan

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

Kode telah dihilangkan dari contoh ini.

Gunakan Kuas sebagai Masker Opasitas dengan Metode FillGeometry

Bagian sebelumnya menjelaskan cara menggunakan ID2D1Bitmap sebagai masker opasitas. Direct2D juga menyediakan metode ID2D1RenderTarget::FillGeometry , yang memungkinkan Anda untuk secara opsional menentukan kuas sebagai masker opasitas saat Anda mengisi ID2D1Geometry. Ini memungkinkan Anda membuat masker opasitas dari gradien (menggunakan ID2D1LinearGradientBrush atau ID2D1RadialGradientBrush) dan bitmap (menggunakan ID2D1Bitmap).

Metode FillGeometry mengambil tiga parameter:

Bagian berikut menjelaskan cara menggunakan objek ID2D1LinearGradientBrush dan ID2D1RadialGradientBrush sebagai masker opasitas.

Menggunakan Sikat Gradien Linear sebagai Masker Opasitas

Diagram berikut menunjukkan efek menerapkan kuas gradien linier ke persegi panjang yang diisi dengan bitmap bunga.

diagram bitmap bunga dengan kuas gradien linier yang diterapkan

Langkah-langkah berikut menjelaskan cara membuat ulang efek ini.

  1. Tentukan konten yang akan diselubungi. Contoh berikut membuat ID2D1BitmapBrush, m_pLinearFadeFlowersBitmap. Mode perluas x- dan y- untuk m_pLinearFadeFlowersBitmap diatur ke D2D1_EXTEND_MODE_CLAMP sehingga dapat digunakan dengan masker opasitas dengan metode 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. Tentukan masker opasitas. Contoh kode berikutnya membuat sikat gradien linier diagonal (m_pLinearGradientBrush) yang memudar dari hitam yang sepenuhnya buram pada posisi 0 hingga putih sepenuhnya transparan pada posisi 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. Gunakan metode FillGeometry . Contoh terakhir menggunakan metode FillGeometry ke kuas konten untuk mengisi ID2D1RectangleGeometry (m_pRectGeo) dengan ID2D1BitmapBrush (m_pLinearFadeFlowersBitmap) dan menerapkan masker opasitas (m_pLinearGradientBrush).
            m_pRenderTarget->FillGeometry(
                m_pRectGeo, 
                m_pLinearFadeFlowersBitmapBrush, 
                m_pLinearGradientBrush
                );

Kode telah dihilangkan dari contoh ini.

Menggunakan Sikat Gradien Radial sebagai Masker Opacity

Diagram berikut menunjukkan efek visual menerapkan kuas gradien radial ke persegi panjang yang diisi dengan bitmap dedaunan.

diagram bitmap dedaunan dengan kuas gradien radial diterapkan

Contoh pertama membuat ID2D1BitmapBrush, m_pRadialFadeFlowersBitmapBrush. Sehingga dapat digunakan dengan masker opasitas dengan metode FillGeometry , mode perluasan x- dan y- untuk m_pRadialFadeFlowersBitmapBrush diatur ke 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++
            }

Contoh berikutnya mendefinisikan kuas gradien radial yang akan digunakan sebagai masker opasitas.

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

Contoh kode akhir menggunakan ID2D1BitmapBrush (m_pRadialFadeFlowersBitmapBrush) dan masker opasitas (m_pRadialGradientBrush) untuk mengisi ID2D1RectangleGeometry (m_pRectGeo).

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

Kode telah dihilangkan dari contoh ini.

Menerapkan Masker Opacity ke Lapisan

Ketika Anda memanggil PushLayer untuk mendorong ID2D1Layer ke target render, Anda dapat menggunakan struktur D2D1_LAYER_PARAMETERS untuk menerapkan kuas sebagai masker opasitas. Contoh kode berikut menggunakan ID2D1RadialGradientBrush sebagai masker opasitas.

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

Untuk informasi selengkapnya tentang menggunakan lapisan, lihat Gambaran Umum Lapisan.

Gambaran Umum Brush

Gambaran Umum Lapisan