I'm loading an image into a TPaintBox
, then try to rotate it with SetWorldTransform as suggested in this answer:
The picture loads fine via the TPaintBox.Invalidate -> TPaintBox.OnPaint
.
But when I click the test button BtnRotateWorldTransform
,
I see the image flicker but no rotation.
procedure TFrmRotateImage.FormCreate(Sender: TObject);
begin
FWICImage := TWICImage.Create;
end;
procedure TFrmRotateImage.BtnLoadPaintBoxClick(Sender: TObject);
begin
if DlgOpen.Execute then // PNG or JPG file
begin
try
FWICImage.LoadFromFile(DlgOpen.FileName);
FBoxLoaded := true;
PaintBox.Invalidate;
finally
end;
end;
end;
procedure TFrmRotateImage.PaintBoxPaint(Sender: TObject); // OnPaint handler
begin
if not FBoxLoaded then Exit;
PaintBox.Canvas.Draw(0,0,FWICImage);
end;
procedure TFrmRotateImage.BtnRotateWorldTransformClick(Sender: TObject); // Test button
var
lRect: TRect;
begin
lRect.Top := PaintBox.Top;
lRect.Left := PaintBox.Left;
lRect.Width := PaintBox.Width;
lRect.Height := PaintBox.Height;
StretchDrawRotated(PaintBox.Canvas,lRect,90,lRect.CenterPoint,FWICImage);
PaintBox.Invalidate;
end;
with
procedure XForm_SetRotation(out AXForm: TXForm; AAngle: Extended; ACenter: TPoint);
var
SinA, CosA: Extended;
begin
SinCos(AAngle, SinA, CosA);
AXForm.eM11 := CosA;
AXForm.eM12 := SinA;
AXForm.eM21 := -SinA;
AXForm.eM22 := CosA;
AXForm.eDx := (ACenter.X - (CosA * ACenter.X)) + ((SinA * ACenter.Y));
AXForm.eDy := (ACenter.Y - (SinA * ACenter.X)) - ((CosA * ACenter.Y));
end;
procedure StretchDrawRotated(ACanvas: TCanvas; const ARect: TRect; AAngle: Extended; ACenter: TPoint; AGraphic: TGraphic);
var
XForm, XFormOld: TXForm;
GMode: Integer;
begin
GMode := SetGraphicsMode(ACanvas.Handle, GM_ADVANCED);
try
if GetWorldTransform(ACanvas.Handle, XFormOld) then
try
XForm_SetRotation(XForm, AAngle, ACenter);
SetWorldTransform(ACanvas.Handle, XForm);
ACanvas.StretchDraw(ARect, AGraphic);
finally
SetWorldTransform(ACanvas.Handle, XFormOld);
end;
finally
SetGraphicsMode(ACanvas.Handle, GMode);
end;
end;
What am I forgetting?