Cenni preliminari sulle maschere di opacità
Questo argomento descrive come usare bitmap e pennelli per definire maschere di opacità. Include le sezioni seguenti:
- Prerequisiti
- Che cos'è una maschera di opacità?
- Usare una bitmap come maschera di opacità con il metodo FillOpacityMask
- Usare un pennello come maschera di opacità con il metodo FillGeometry
- Applicare una maschera di opacità a un livello
- Argomenti correlati
Prerequisiti
Questa panoramica presuppone che si abbia familiarità con le operazioni di disegno Direct2D di base, come descritto nella procedura dettagliata Creare una semplice applicazione Direct2D . È anche necessario avere familiarità con i diversi tipi di pennelli, come descritto in Cenni preliminari sui pennelli.
Che cos'è una maschera di opacità?
Una maschera di opacità è una maschera, descritta da un pennello o una bitmap, applicata a un altro oggetto per rendere l'oggetto parzialmente o completamente trasparente. Una maschera di opacità usa informazioni sul canale alfa per specificare la modalità di fusione dei pixel di origine dell'oggetto nella destinazione finale. Le parti trasparenti della maschera indicano le aree in cui l'immagine sottostante è nascosta, mentre le parti opache della maschera indicano dove l'oggetto mascherato è visibile.
Esistono diversi modi per applicare una maschera di opacità:
- Usare il metodo ID2D1RenderTarget::FillOpacityMask . Il metodo FillOpacityMask disegna un'area rettangolare di una destinazione di rendering e quindi applica una maschera di opacità, definita da una bitmap. Usa questo metodo quando la maschera di opacità è una bitmap e vuoi riempire un'area rettangolare.
- Usare il metodo ID2D1RenderTarget::FillGeometry . Il metodo FillGeometry disegna l'interno della geometria con l'ID2D1BitmapBrush specificato, quindi applica una maschera di opacità, definita da un pennello. Utilizzare questo metodo quando si desidera applicare una maschera di opacità a una geometria o si vuole usare un pennello come maschera di opacità.
- Usare un ID2D1Layer per applicare una maschera di opacità. Utilizzare questo approccio quando si desidera applicare una maschera di opacità a un gruppo di contenuto di disegno, non solo a una singola forma o immagine. Per informazioni dettagliate, vedere Panoramica dei livelli.
Usare una bitmap come maschera di opacità con il metodo FillOpacityMask
Il metodo FillOpacityMask disegna un'area rettangolare di una destinazione di rendering e quindi applica una maschera di opacità definita da id2D1Bitmap. Usa questo metodo quando hai una bitmap che vuoi usare come maschera di opacità per un'area rettangolare.
Il diagramma seguente mostra un effetto dell'applicazione della maschera di opacità ( ID2D1Bitmap con un'immagine di un fiore) a un oggetto ID2D1BitmapBrush con un'immagine di una pianta di felce. L'immagine risultante è una bitmap di una pianta ritagliata alla forma del fiore.
Gli esempi di codice seguenti illustrano come viene eseguita questa operazione.
Il primo esempio carica la bitmap seguente, m_pBitmapMask, da usare come maschera bitmap. La figura seguente mostra l'output prodotto. Si noti che, anche se la parte opaca della bitmap appare nera, le informazioni sul colore nella bitmap non hanno alcun effetto sulla maschera di opacità; vengono usate solo le informazioni di opacità di ogni pixel nella bitmap. I pixel completamente opachi in questa bitmap sono stati colorati in nero solo a scopo illustrativo.
In questo esempio l'ID2D1Bitmap viene caricato da un metodo helper, LoadResourceBitmap, definito altrove nell'esempio.
if (SUCCEEDED(hr))
{
hr = LoadResourceBitmap(
m_pRenderTarget,
m_pWICFactory,
L"BitmapMask",
L"Image",
&m_pBitmapMask
);
}
Nell'esempio seguente viene definito il pennello m_pFernBitmapBrush a cui viene applicata la maschera di opacità. In questo esempio viene usato un oggetto ID2D1BitmapBrush che contiene un'immagine di una felce, ma è possibile usare invece id2D1SolidColorBrush, ID2D1LinearGradientBrush o ID2D1RadialGradientBrush . La figura seguente mostra l'output prodotto.
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
);
}
Ora che la maschera di opacità e il pennello sono definiti, è possibile usare il metodo FillOpacityMask nel metodo di rendering dell'applicazione. Quando si chiama il metodo FillOpacityMask , è necessario specificare il tipo di maschera di opacità in uso: D2D1_OPACITY_MASK_CONTENT_GRAPHICS, D2D1_OPACITY_MASK_CONTENT_TEXT_NATURAL e D2D1_OPACITY_MASK_CONTENT_TEXT_GDI_COMPATIBLE. Per i significati di questi tre tipi, vedere D2D1_OPACITY_MASK_CONTENT.
Nota
A partire da Windows 8, il D2D1_OPACITY_MASK_CONTENT non è obbligatorio. Vedere il metodo ID2D1DeviceContext::FillOpacityMask , che non ha alcun parametro D2D1_OPACITY_MASK_CONTENT .
Nell'esempio seguente viene impostata la modalità di anti-aliasing della destinazione di rendering su D2D1_ANTIALIAS_MODE_ALIASED in modo che la maschera di opacità funzioni correttamente. Chiama quindi il metodo FillOpacityMask e lo passa la maschera di opacità (m_pBitmapMask), il pennello a cui viene applicata la maschera di opacità (m_pFernBitmapBrush), il tipo di contenuto all'interno della maschera di opacità (D2D1_OPACITY_MASK_CONTENT_GRAPHICS) e l'area da disegnare. La figura seguente mostra l'output prodotto.
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);
Il codice è stato omesso da questo esempio.
Usare un pennello come maschera di opacità con il metodo FillGeometry
La sezione precedente ha descritto come usare un ID2D1Bitmap come maschera di opacità. Direct2D fornisce anche il metodo ID2D1RenderTarget::FillGeometry , che consente di specificare facoltativamente il pennello come maschera di opacità quando si riempie un oggetto ID2D1Geometry. In questo modo è possibile creare maschere di opacità da sfumature (usando ID2D1LinearGradientBrush o ID2D1RadialGradientBrush) e bitmap (tramite ID2D1Bitmap).
Il metodo FillGeometry accetta tre parametri:
- Il primo parametro, id2D1Geometry, definisce la forma da disegnare.
- Il secondo parametro, ID2D1Brush, specifica il pennello utilizzato per disegnare la geometria. Questo parametro deve essere un oggetto ID2D1BitmapBrush con le relative modalità di estensione x e y impostate su D2D1_EXTEND_MODE_CLAMP.
- Il terzo parametro, ID2D1Brush, specifica un pennello da usare come maschera di opacità. Questo pennello può essere id2D1LinearGradientBrush, ID2D1RadialGradientBrush o ID2D1BitmapBrush. Tecnicamente, è possibile usare un oggetto ID2D1SolidColorBrush, ma l'uso di un pennello a tinta unita come maschera di opacità non produce risultati interessanti.
Le sezioni seguenti descrivono come usare gli oggetti ID2D1LinearGradientBrush e ID2D1RadialGradientBrush come maschere di opacità.
Usare un pennello sfumato lineare come maschera di opacità
Il diagramma seguente illustra l'effetto dell'applicazione di un pennello sfumato lineare a un rettangolo riempito con una bitmap di fiori.
I passaggi seguenti descrivono come ricreare questo effetto.
Definire il contenuto da mascherare. Nell'esempio seguente viene creato un m_pLinearFadeFlowersBitmap ID2D1BitmapBrush. La modalità di estensione x e y- per m_pLinearFadeFlowersBitmap è impostata su D2D1_EXTEND_MODE_CLAMP in modo che possa essere usata con una maschera di opacità tramite il metodo 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++ }
Definire la maschera di opacità. Nell'esempio di codice seguente viene creato un pennello sfumato lineare diagonale (m_pLinearGradientBrush) che si dissolve dal nero completamente opaco nella posizione 0 al bianco completamente trasparente nella posizione 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();
}
- Usare il metodo FillGeometry . L'esempio finale usa il metodo FillGeometry per il pennello di contenuto per riempire un oggetto ID2D1RectangleGeometry (m_pRectGeo) con id2D1BitmapBrush (m_pLinearFadeFlowersBitmap) e applica una maschera di opacità (m_pLinearGradientBrush).
m_pRenderTarget->FillGeometry(
m_pRectGeo,
m_pLinearFadeFlowersBitmapBrush,
m_pLinearGradientBrush
);
Il codice è stato omesso da questo esempio.
Usare un pennello sfumato radiale come maschera di opacità
Il diagramma seguente illustra l'effetto visivo dell'applicazione di un pennello sfumato radiale a un rettangolo riempito con una bitmap di fogliame.
Il primo esempio crea un m_pRadialFadeFlowersBitmapBrush ID2D1BitmapBrush. In modo che possa essere usata con una maschera di opacità dal metodo FillGeometry , la modalità di estensione x e y- per m_pRadialFadeFlowersBitmapBrush sono impostate su 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++ |
---|
|
Nell'esempio seguente viene definito il pennello sfumato radiale che verrà usato come maschera di opacità.
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();
}
L'esempio di codice finale usa id2D1BitmapBrush (m_pRadialFadeFlowersBitmapBrush) e la maschera di opacità (m_pRadialGradientBrush) per riempire un oggettoID2D1RectangleGeometry (m_pRectGeo).
m_pRenderTarget->FillGeometry(
m_pRectGeo,
m_pRadialFadeFlowersBitmapBrush,
m_pRadialGradientBrush
);
Il codice è stato omesso da questo esempio.
Applicare una maschera di opacità a un livello
Quando chiami PushLayer per eseguire il push di un ID2D1Layer in una destinazione di rendering, puoi usare la struttura D2D1_LAYER_PARAMETERS per applicare un pennello come maschera di opacità. Nell'esempio di codice seguente viene usato un oggetto ID2D1RadialGradientBrush come maschera di opacità.
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;
}
Per altre informazioni sull'uso dei livelli, vedere Panoramica dei livelli.
Argomenti correlati