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;
运行效果图: