Direct2D (17) : 蒙版之 FillGeometry() 方法


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;

运行效果图:

Direct2D (17) : 蒙版之 FillGeometry() 方法_第1张图片

修改为使用线性渐变画刷做蒙版:
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;

运行效果图:

Direct2D (17) : 蒙版之 FillGeometry() 方法_第2张图片

你可能感兴趣的:(Direct2D (17) : 蒙版之 FillGeometry() 方法)