• 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;
    


    运行效果图:




    修改为使用线性渐变画刷做蒙版:

    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;
    


    运行效果图:



  • 相关阅读:
    【BZOJ2138】stone
    【ARC076F】 Exhausted
    [SDOI2018]战略游戏
    CF536D Tavas in Kansas
    [JSOI2018]战争
    ###学习《C++ Primer》- 5
    ###学习《C++ Primer》- 4
    ###Linux基础
    ###Linux基础
    ###Linux基础
  • 原文地址:https://www.cnblogs.com/del/p/2005750.html
Copyright © 2020-2023  润新知