Átlátszatlansági maszkok áttekintése
Ez a témakör azt ismerteti, hogyan definiálhat átlátszatlansági maszkokat bitképekkel és ecsetekkel. A következő szakaszokat tartalmazza.
- előfeltételek
- Mi az az átlátszatlansági maszk?
- Bitkép használata átlátszatlansági maszkként a FillOpacityMask metódussal
- Ecset használata átlátszatlansági maszkként a FillGeometry metódussal
- Átlátszatlansági maszk alkalmazása rétegre
- Kapcsolódó témakörök
Előfeltételek
Ez az áttekintés feltételezi, hogy ismeri az egyszerű Direct2D-rajzműveleteket az Egyszerű Direct2D-alkalmazás létrehozása útmutatóban leírtak szerint. Ismernie kell a különböző típusú keféket is, ahogyan az Ecsetek áttekintésecímű cikkben leírtak szerint.
Mi az az átlátszatlansági maszk?
Az átlátszatlansági maszk egy ecsettel vagy bitképtel leírt maszk, amelyet egy másik objektumra alkalmazva részlegesen vagy teljesen áttetszővé teszi az objektumot. Az átlátszatlansági maszk alfa csatornainformációkat használ annak megadásához, hogy az objektum forrás képpontjai hogyan lesznek beolvadva a végső célhelyre. A maszk áttetsző részei jelzik azokat a területeket, ahol az alapul szolgáló kép rejtett, míg a maszk átlátszatlan részei jelzik, hogy hol látható a maszkolt objektum.
Az átlátszatlansági maszkok többféleképpen is alkalmazhatók:
- Használja a ID2D1RenderTarget::FillOpacityMask metódust. A FillOpacityMask metódus egy renderelési cél négyszögletes régióját festi, majd bitkép által definiált átlátszatlansági maszkot alkalmaz. Ezt a módszert akkor használja, ha az átlátszatlansági maszk bitkép, és téglalap alakú régiót szeretne kitölteni.
- Használja a ID2D1RenderTarget::FillGeometry metódust. A FillGeometry metódus a geometria belsejét a megadott ID2D1BitmapBrushsegítségével festi, majd egy ecsettel meghatározott átlátszatlansági maszkot alkalmaz. Ezt a módszert akkor használhatja, ha átlátszatlansági maszkot szeretne alkalmazni egy geometriára, vagy ha átlátszatlansági maszkként szeretne ecsetet használni.
- Használjon ID2D1Layer opacitásmaszkot. Ezt a módszert akkor használja, ha átlátszatlansági maszkot szeretne alkalmazni rajztartalmak egy csoportjára, nem csak egyetlen alakzatra vagy képre. További információt a Rétegek áttekintésecímű témakörben talál.
Bitkép használata opacitásmaszkként a FillOpacityMask metódussal
A FillOpacityMask metódus egy renderelési cél téglalap alakú régióját festi, majd egy ID2D1Bitmapáltal meghatározott opacitásmaszkot alkalmaz. Ezt a módszert akkor használja, ha olyan bitképet használ, amelyet átlátszatlansági maszkként szeretne használni egy téglalap alakú régióhoz.
Az alábbi ábra azt mutatja be, hogyan hat az átlátszatlansági maszk (egy ID2D1Bitmap virág képével) egy ID2D1BitmapBrush, egy páfránynövény képével. Az így kapott kép egy növény bitképe, amelyet egy virág formájára vágtak.
Az alábbi példakód bemutatja, hogyan történik ez a feladat.
Az első példa a következő bitképet tölti be, m_pBitmapMaskbitképmaszkként való használatra. Az alábbi ábrán a létrehozott kimenet látható. Vegye figyelembe, hogy bár a bitkép átlátszatlan része fekete színnel jelenik meg, a bitkép színadatainak nincs hatása az átlátszatlansági maszkra; csak a bitképben lévő egyes képpontok átlátszósági információi használhatók. A teljes átlátszatlan képpontok ebben a bitképben fekete színűek voltak csak szemléltető célokra.
Ebben a példában az ID2D1Bitmap egy, a mintában máshol definiált LoadResourceBitmap nevű segédmetódus tölti be.
if (SUCCEEDED(hr))
{
hr = LoadResourceBitmap(
m_pRenderTarget,
m_pWICFactory,
L"BitmapMask",
L"Image",
&m_pBitmapMask
);
}
A következő példa azt az ecsetet határozza meg, m_pFernBitmapBrush, amelyre az átlátszatlansági maszkot alkalmazza. Ez a példa egy ID2D1BitmapBrush használ, amely egy páfrány képét tartalmazza, de használhat helyette egy ID2D1SolidColorBrush, ID2D1LinearGradientBrushvagy ID2D1RadialGradientBrush. Az alábbi ábrán a létrehozott kimenet látható.
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
);
}
Most, hogy definiálta az átlátszatlansági maszkot és az ecsetet, használhatja a FillOpacityMask metódust az alkalmazás renderelési módszerében. Amikor meghívja a FillOpacityMask metódust, meg kell adnia a használt opacitásmaszk típusát: D2D1_OPACITY_MASK_CONTENT_GRAPHICS, D2D1_OPACITY_MASK_CONTENT_TEXT_NATURALés D2D1_OPACITY_MASK_CONTENT_TEXT_GDI_COMPATIBLE. A három típus jelentéséről lásd: D2D1_OPACITY_MASK_CONTENT.
Jegyzet
A Windows 8-tól kezdve a D2D1_OPACITY_MASK_CONTENT nem szükséges. Lásd a ID2D1DeviceContext::FillOpacityMask metódust, amely nem rendelkezik D2D1_OPACITY_MASK_CONTENT paramétersel.
A következő példa a renderelési cél élsimítási módját D2D1_ANTIALIAS_MODE_ALIASED állítja be, hogy az átlátszatlansági maszk megfelelően működjön. Ezután meghívja a FillOpacityMask metódust, és átadja neki az átlátszatlansági maszkot (m_pBitmapMask), azt az ecsetet, amelyre az átlátszatlansági maszkot alkalmazzák (m_pFernBitmapBrush), az átlátszatlansági maszkon (D2D1_OPACITY_MASK_CONTENT_GRAPHICS) belüli tartalom típusát és a festendő területet. Az alábbi ábrán a létrehozott kimenet látható.
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);
Ebből a példából kihagyta a kódot.
Ecset használata átlátszatlansági maszkként a FillGeometry metódussal
Az előző szakasz bemutatta, hogyan használható ID2D1Bitmap átlátszatlansági maszkként. A Direct2D az ID2D1RenderTarget::FillGeometry metódust is biztosítja, amely lehetővé teszi, hogy szükség esetén átlátszatlansági maszkként adja meg az ecsetet az ID2D1Geometry kitöltésekor. Ez lehetővé teszi átlátszatlansági maszkok létrehozását színátmenetekből (ID2D1LinearGradientBrush vagy ID2D1RadialGradientBrush) és bitképekből (ID2D1Bitmap).
A FillGeometry metódus három paramétert használ:
- Az első paraméter, egy ID2D1Geometryhatározza meg a festendő alakzatot.
- A második paraméter, egy ID2D1Brush, megadja a geometria festéséhez használt ecsetet. Ennek a paraméternek egy ID2D1BitmapBrush kell lennie, amelynek x és y kiterjesztésű üzemmódja D2D1_EXTEND_MODE_CLAMP.
- A harmadik paraméter, egy ID2D1Brush, egy átlátszatlansági maszkként használandó ecsetet ad meg. Ez az ecset lehet egy ID2D1LinearGradientBrush, ID2D1RadialGradientBrush, vagy ID2D1BitmapBrush. (Technikailag használhatunk egy ID2D1SolidColorBrush, de egy egyszínű ecset átlátszósági maszkként való használata nem hoz igazán érdekes eredményeket.)
A következő szakaszok ismertetik, hogyan használható ID2D1LinearGradientBrush és ID2D1RadialGradientBrush objektumokat átlátszatlansági maszkként.
Lineáris színátmenetes ecset használata átlátszatlansági maszkként
Az alábbi ábra azt mutatja, hogy egy lineáris színátmenetű ecset hatását alkalmazzuk egy téglalapra, amely virágok bitmapjével van kitöltve.
Az alábbi lépések bemutatják, hogyan hozhatja létre újra ezt az effektust.
Határozza meg a maszkolandó tartalmat. Az alábbi példa létrehoz egy ID2D1BitmapBrush, m_pLinearFadeFlowersBitmap. A m_pLinearFadeFlowersBitmap x és y kiterjesztési módja D2D1_EXTEND_MODE_CLAMP van beállítva, hogy a FillGeometry metódus használhassa átlátszatlansági maszkkal.
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++ }
Adja meg az átlátszatlansági maszkot. A következő példakód egy átlós lineáris gradiens ecsetet hoz létre (m_pLinearGradientBrush), amely a 0. pozícióban teljesen átlátszatlan feketéről teljesen átlátszó fehérre halványul az 1. pozícióban.
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();
}
- Használja a FillGeometry metódust. Az utolsó példa a FillGeometry metódust használja a tartalomkefével a ID2D1RectangleGeometry (m_pRectGeo) kitöltésére egy ID2D1BitmapBrush segítségével (m_pLinearFadeFlowersBitmap), és egy átlátszósági maszkot (m_pLinearGradientBrush) alkalmaz.
m_pRenderTarget->FillGeometry(
m_pRectGeo,
m_pLinearFadeFlowersBitmapBrush,
m_pLinearGradientBrush
);
Ebből a példából kihagyta a kódot.
Sugárirányú színátmenetes ecset használata átlátszósági maszkként
Az alábbi ábra azt mutatja be, hogy milyen vizuális hatása van annak, ha egy gradiens kefét alkalmazunk egy olyan téglalapra, amely tele van lombozat bitképével.
Az első példa létrehoz egy ID2D1BitmapBrush, m_pRadialFadeFlowersBitmapBrush. Annak érdekében, hogy az FillGeometry metódus átlátszatlansági maszkkal is használható legyen, a m_pRadialFadeFlowersBitmapBrush x- és y-irányú kiterjesztési módja 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++ |
---|
|
C++ |
---|
|
A következő példa meghatározza a radiális gradiens ecsetet, amely átlátszatlansági maszkként lesz használva.
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();
}
Az utolsó példakód az ID2D1BitmapBrush (m_pRadialFadeFlowersBitmapBrush) és az átlátszatlansági maszk (m_pRadialGradientBrush) használatával tölt ki egy ID2D1RectangleGeometry (m_pRectGeo).
m_pRenderTarget->FillGeometry(
m_pRectGeo,
m_pRadialFadeFlowersBitmapBrush,
m_pRadialGradientBrush
);
Ebből a példából kihagyta a kódot.
Átlátszatlansági maszk alkalmazása rétegre
Amikor meghívja a PushLayer-t egy ID2D1Layer renderelési célpontba történő leküldéséhez, a D2D1_LAYER_PARAMETERS struktúrát használhatja egy ecset átlátszatlansági maszkként való alkalmazására. Az alábbi példakód egy ID2D1RadialGradientBrush-t használja átlátszósági maszkként.
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;
}
További információ a rétegek használatáról: Rétegek áttekintése.
Kapcsolódó témakörök