FillGeometry() 可通过两个画刷的重叠运算获取蒙版效果,作为蒙版画刷的渐变色中应该至少有一个透明色。
使用放射渐变画刷做蒙版:
uses Direct2D, D2D1, Wincodec, ActiveX; {从指定文件建立 ID2D1Bitmap 的函数} function GetD2D1Bitmap(RenderTarget: ID2D1RenderTarget; imgPath: string): ID2D1Bitmap; var iWicFactory: IWICImagingFactory; iWICDecoder: IWICBitmapDecoder; iWICFrameDecode: IWICBitmapFrameDecode; iFormatConverter: IWICFormatConverter; begin CoCreateInstance(CLSID_WICImagingFactory, nil, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, iWicFactory); iWicFactory.CreateDecoderFromFilename(PWideChar(imgPath), GUID_NULL, GENERIC_READ, WICDecodeMetadataCacheOnLoad, iWICDecoder); iWicDecoder.GetFrame(0, iWICFrameDecode); iWicFactory.CreateFormatConverter(iFormatConverter); iFormatConverter.Initialize(iWICFrameDecode, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nil, 0, WICBitmapPaletteTypeMedianCut); RenderTarget.CreateBitmapFromWicBitmap(iFormatConverter, nil, Result); end; procedure TForm1.FormPaint(Sender: TObject); var cvs: TDirect2DCanvas; iBitmapBrush: ID2D1BitmapBrush; iBitmapPic: ID2D1Bitmap; rRectF: TD2DRectF; rSizeF: TD2DSizeF; iRectangleGeometry: ID2D1RectangleGeometry; iRadialGradientBrush: ID2D1RadialGradientBrush; rRGBP: TD2D1RadialGradientBrushProperties; arrGradientStop: array[0..1] of TD2D1GradientStop; iGradientStops: ID2D1GradientStopCollection; begin cvs := TDirect2DCanvas.Create(Canvas, ClientRect); iBitmapPic := GetD2D1Bitmap(cvs.RenderTarget, 'C:\Temp\Test.png'); cvs.RenderTarget.CreateBitmapBrush(iBitmapPic, nil, nil, iBitmapBrush); iBitmapPic.GetSize(rSizeF); rRectF := D2D1RectF(0, 0, rSizeF.width, rSizeF.height); rRGBP.center := D2D1PointF(rRectF.right / 2, rRectF.bottom / 2); rRGBP.gradientOriginOffset := D2D1PointF(0, 0); rRGBP.radiusX := (rRectF.Right - rRectF.Left) / 2; rRGBP.radiusY := (rRectF.Bottom - rRectF.Top) / 2; arrGradientStop[0].position := 0.0; arrGradientStop[0].color := D2D1ColorF(clYellow, 0.0); //关键代码:颜色值不重要,重要的是透明度,该色被指定为全透明 arrGradientStop[1].position := 1.0; arrGradientStop[1].color := D2D1ColorF(clRed, 1.0); //不透明;测试图片有置换这个两个透明度的演示 cvs.RenderTarget.CreateGradientStopCollection(@arrGradientStop[0], Length(arrGradientStop), D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP, iGradientStops); cvs.RenderTarget.CreateRadialGradientBrush(rRGBP, nil, iGradientStops, iRadialGradientBrush); cvs.BeginDraw; cvs.RenderTarget.Clear(D2D1ColorF(clWhite)); //填充背景 cvs.RenderTarget.SetTransform(TD2DMatrix3x2F.Translation((ClientWidth-rSizeF.width)/2, (ClientHeight-rSizeF.height)/2)); // cvs.RenderTarget.SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED); D2DFactory.CreateRectangleGeometry(rRectF, iRectangleGeometry); cvs.RenderTarget.FillGeometry(iRectangleGeometry, iBitmapBrush, iRadialGradientBrush); // cvs.RenderTarget.SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); cvs.EndDraw; cvs.Free; end; procedure TForm1.FormResize(Sender: TObject); begin Repaint; end;
运行效果图:
修改为使用线性渐变画刷做蒙版:
uses Direct2D, D2D1, Wincodec, ActiveX; {从指定文件建立 ID2D1Bitmap 的函数} function GetD2D1Bitmap(RenderTarget: ID2D1RenderTarget; imgPath: string): ID2D1Bitmap; var iWicFactory: IWICImagingFactory; iWICDecoder: IWICBitmapDecoder; iWICFrameDecode: IWICBitmapFrameDecode; iFormatConverter: IWICFormatConverter; begin CoCreateInstance(CLSID_WICImagingFactory, nil, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, iWicFactory); iWicFactory.CreateDecoderFromFilename(PWideChar(imgPath), GUID_NULL, GENERIC_READ, WICDecodeMetadataCacheOnLoad, iWICDecoder); iWicDecoder.GetFrame(0, iWICFrameDecode); iWicFactory.CreateFormatConverter(iFormatConverter); iFormatConverter.Initialize(iWICFrameDecode, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nil, 0, WICBitmapPaletteTypeMedianCut); RenderTarget.CreateBitmapFromWicBitmap(iFormatConverter, nil, Result); end; procedure TForm1.FormPaint(Sender: TObject); var cvs: TDirect2DCanvas; iBitmapBrush: ID2D1BitmapBrush; iBitmapPic: ID2D1Bitmap; rRectF: TD2DRectF; rSizeF: TD2DSizeF; iRectangleGeometry: ID2D1RectangleGeometry; iLinearGradientBrush: ID2D1LinearGradientBrush; rLinear: TD2D1LinearGradientBrushProperties; arrGradientStop: array[0..1] of TD2D1GradientStop; iGradientStops: ID2D1GradientStopCollection; begin cvs := TDirect2DCanvas.Create(Canvas, ClientRect); iBitmapPic := GetD2D1Bitmap(cvs.RenderTarget, 'C:\Temp\Test.png'); cvs.RenderTarget.CreateBitmapBrush(iBitmapPic, nil, nil, iBitmapBrush); iBitmapPic.GetSize(rSizeF); rRectF := D2D1RectF(0, 0, rSizeF.width, rSizeF.height); rLinear.startPoint := D2D1PointF(0, 0); rLinear.endPoint := D2D1PointF(rSizeF.width, rSizeF.height); arrGradientStop[0].position := 0.0; arrGradientStop[0].color := D2D1ColorF(clYellow, 0.0); arrGradientStop[1].position := 1.0; arrGradientStop[1].color := D2D1ColorF(clRed, 1.0); cvs.RenderTarget.CreateGradientStopCollection(@arrGradientStop[0], Length(arrGradientStop), D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP, iGradientStops); cvs.RenderTarget.CreateLinearGradientBrush(rLinear, nil, iGradientStops, iLinearGradientBrush); cvs.BeginDraw; cvs.RenderTarget.Clear(D2D1ColorF(clWhite)); cvs.RenderTarget.SetTransform(TD2DMatrix3x2F.Translation((ClientWidth-rSizeF.width)/2, (ClientHeight-rSizeF.height)/2)); D2DFactory.CreateRectangleGeometry(rRectF, iRectangleGeometry); cvs.RenderTarget.FillGeometry(iRectangleGeometry, iBitmapBrush, iLinearGradientBrush); cvs.EndDraw; cvs.Free; end; procedure TForm1.FormResize(Sender: TObject); begin Repaint; end;
运行效果图: