Как повернуть и нарисовать прозрачное 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;