下午好。
我正在开发一个绘图程序,允许用户在画布上拖放加载了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不会考虑窗口中可见图像的缩放和旋转的转换,并且在保存时会丢失。 我正在寻找一种方法,在将位图绘制到背景之前将变换应用于位图。 我无法找到任何关于此的信息,所以我希望有人可以提供帮助。
谢谢你, 丹尼尔
答案 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;