3

下午好。

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

  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 没有考虑到窗口中可见图像的缩放和旋转的转换,并且在保存时会丢失。我正在寻找一种在将位图绘制到背景之前将转换应用于位图的方法。我无法找到有关此的任何信息,所以我希望这里有人可以提供帮助。

谢谢你,丹尼尔

4

1 回答 1

2

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

因此必须根据源 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;
于 2012-09-01T15:27:46.330 回答