Рисуй на TeeChart напрямую с помощью GDI + - PullRequest
0 голосов
/ 27 августа 2018

Как повернуть и нарисовать прозрачное PNG-изображение, используя GDI + непосредственно на TChart?

В настоящее время я загружаю PNG-изображение в растровое изображение и использую два растровых изображения для вращения GDI + (это работает очень быстро), а затем задаю цельПрозрачное растровое изображение и нарисуйте его на холсте TChart (оно работает медленно, когда включена прозрачность).

procedure TPitchDisplay._chartAfterDraw(Sender: TObject);
var
  c: TCanvas3D;
  pw, ph: Integer;
  r: TRect;
  bmp: TBitmap;
  rotAngle: Integer;
begin
  _setKnobBounds();
  c := _chart.Canvas;
  _drawCircle(c, _knob.CenterPoint.X, _knob.CenterPoint.Y, Round(_knob.YRadius * 0.9));
  c.StretchDrawQuality := sqHigh;
  pw := 450;
  ph := Round((pw / _shipBitmap.Width) * _shipBitmap.Height);
  r.Left := _chart.ChartXCenter - pw div 2;
  r.Top := Round(_chart.Height / 3);
  r.Width := pw;
  r.Height := ph;

  //Draw water
  c.StretchDraw(Rect(0, r.Top + Round(ph / 1.5), _chart.Width, _chart.Height), _waterBitmap);

  //Draw rotated ship over it
  bmp := TBitmap.Create();
  try
    bmp.Width := Round(_shipBitmap.Width * 1.2);
    bmp.Height := Round(_shipBitmap.Height * 1.7);
    bmp.TransparentColor := clBlack;
    bmp.Transparent := True;
    bmp.TransparentMode := TTransparentMode.tmFixed;
    if VarIsNumeric(_pitchBox.Value) then
      rotAngle := _pitchBox.Value
    else
      rotAngle := 0;
    TGraphUtils.RotateBitmap(_shipBitmap, bmp, 0.5, 0.7, rotAngle, False, clBlack);
    c.StretchDraw(r, bmp);
  finally
    bmp.Free();
  end;
end;

Процедура вращения:

class procedure TGraphUtils.RotateBitmap(srcBmp, tgtBmp: TBitmap; rotateAtX, rotateAtY: Single; Degs: Integer; AdjustSize: Boolean;
  BkColor: TColor = clNone);
var
  Tmp: TGPBitmap;
  Matrix: TGPMatrix;
  C: Single;
  S: Single;
  NewSize: TSize;
  Graphs: TGPGraphics;
  P: TGPPointF;
  attr: TGPImageAttributes;
begin
  Tmp := TGPBitmap.Create(srcBmp.Handle, srcBmp.Palette);
  Matrix := TGPMatrix.Create();
  try
    Matrix.RotateAt(Degs, MakePoint(rotateAtX * srcBmp.Width, rotateAtY * srcBmp.Height));
    if AdjustSize then begin
      C := Cos(DegToRad(Degs));
      S := Sin(DegToRad(Degs));
      NewSize.cx := Round(srcBmp.Width * Abs(C) + srcBmp.Height * Abs(S));
      NewSize.cy := Round(srcBmp.Width * Abs(S) + srcBmp.Height * Abs(C));
      tgtBmp.Width := NewSize.cx;
      tgtBmp.Height := NewSize.cy;
    end;
    Graphs := TGPGraphics.Create(tgtBmp.Canvas.Handle);
    attr := TGPImageAttributes.Create;
    try
      Graphs.Clear(ColorRefToARGB(ColorToRGB(BkColor)));
      Graphs.SetTransform(Matrix);
      //attr.SetColorKey($FFFFFF {TGPColor.Blue}, $FFFFFF {TGPColor.Blue}, ColorAdjustTypeBitmap);
      Graphs.DrawImage(Tmp, (Cardinal(tgtBmp.Width) - Tmp.GetWidth) div 2,
        (Cardinal(tgtBmp.Height) - Tmp.GetHeight) div 2);
    finally
      attr.Free();
      Graphs.Free();
    end;
  finally
    Matrix.Free();
    Tmp.Free();
  end;
end;

1 Ответ

0 голосов
/ 27 августа 2018

enter image description here

procedure TForm1.Chart1AfterDraw(Sender: TObject);
var
  GPImage: TGPImage;
  GPGraphics: TGPGraphics;
  Matrix: TGPMatrix;
  c: TCanvas3d;
 begin
  c := Chart1.Canvas;
  GPImage := TGPImage.Create('e:\2.png');
  GPGraphics :=  TGPGraphics.Create(C.Handle);
  Matrix := TGPMatrix.Create;
  Matrix.Rotate(30);
  Matrix.Scale(0.5, 0.5);
  GPGraphics.SetTransform(Matrix);
  GPGraphics.DrawImage(GPImage, 150, 0);
  Matrix.Free;
  GPGraphics.Free;
  GPimage.Free;
end;

Не точный пример вывода в центр формы:

  IM := TGPMatrix.Create;
  IM := Matrix.Clone;
  IM.Invert;
  pc := MakePoint(Width div 2 - GPImage.GetWidth() div 2, 
                  Height div 2 - Integer(GPImage.GetHeight) div 2);
  Im.TransformPoints(pgppoINT(@pc));
  GPGraphics.DrawImage(GPImage, pc);
...