在调用Canvas.DrawBitmap(Firemonkey)之前将转换应用于位图

时间:2012-08-31 10:55:55

标签: delphi bitmap transform delphi-xe2 firemonkey

下午好。

我正在开发一个绘图程序,允许用户在画布上拖放加载了Bitmap的TImages。 (在RAD Studio XE2中的Firemonkey HD应用程序中)然后,用户可以在保存图像之前更改x和y比例和旋转。 所有TImages都保存在一个列表中,然后使用这个简单的过程将该列表写入底层画布:

  for i := 0 to DroppedList.Count - 1 do
  begin
    AImage := DroppedList[i];
    SourceRect.Left := 0;
    SourceRect.Right := AImage.Bitmap.Width;
    SourceRect.Top := 0;
    Sourcerect.Bottom := AImage.Bitmap.Height;

    TargetRect.Left := AImage.Position.X;
    TargetRect.Right := AImage.Position.X + AImage.Bitmap.Width;
    TargetRect.Top := AImage.Position.Y;
    TargetRect.Bottom := AImage.Position.Y + AImage.Bitmap.Height;

    with FImage.Bitmap do
    begin
      Canvas.BeginScene;
      Canvas.DrawBitmap(AImage.Bitmap, SourceRect, TargetRect, 1, True);
      Canvas.EndScene;
      BitmapChanged
    end;
  end;

  FImage.Bitmap.SaveToFile('test.bmp');

这个问题是DrawBitmap不会考虑窗口中可见图像的缩放和旋转的转换,并且在保存时会丢失。 我正在寻找一种方法,在将位图绘制到背景之前将变换应用于位图。 我无法找到任何关于此的信息,所以我希望有人可以提供帮助。

谢谢你, 丹尼尔

1 个答案:

答案 0 :(得分:2)

问题似乎是Scaling和Rotation应用于源TImage。在这个“源TImage”中,转换不是对位图进行的,而是在TImage级别进行的(因为它是TControl,并且所有TControl都可以进行缩放和旋转)。稍后您将源位图复制到其他位置,但实际上此位图从未更改

因此,根据源TImage中的设置,必须在循环中旋转和缩放位图:

with FImage.Bitmap do
begin
  Canvas.BeginScene;     
  LBmp := TBitmap.Create;
  try
    // create a copy on which transformations will be applyed
    LBmp.Assign(AImage.Bitmap); 
    // rotate the local bmp copy according to the source TImage.
    if AImage.RotationAngle <> 0 then
      LBmp.Rotate( AImage.RotationAngle);
    // scale the local bmp copy...
    If AImage.Scale.X <> 1 
      then ;
    Canvas.DrawBitmap(LBmp, SourceRect, TargetRect, 1, True);
  finally
    LBmp.Free;
    Canvas.EndScene;
    BitmapChanged
  end;
end;

这个简单的代码示例很好地解释了这个问题。例如,RotatationAngle是 AImage 的属性,而不是 AImage.Bitmap 的属性。

避免实施转换的解决方法是使用 TControl.MakeScreenshot()。(待验证,这可能会失败)

with FImage.Bitmap do
begin
  Canvas.BeginScene;
  LBmpInclTranformations := AImage.MakeScreenShot;
  Canvas.DrawBitmap(LBmpInclTranformations, SourceRect, TargetRect, 1, True);
  Canvas.EndScene;
  BitmapChanged
end;