Delphi 12 CE中FMX TBitmap.CopyFromBitmap()使用异常求助
Delphi 12 CE中TBitmap.CopyFromBitmap清空目标位图的问题及解决
问题原因
FMX的TBitmap.CopyFromBitmap()方法默认行为是完全替换目标位图的内容,而非在原有内容上叠加复制区域。调用该方法时,它会先重置目标位图的像素缓冲区(相当于清空原有内容),再将指定区域的像素复制进去,这就是你看到原有黄色背景消失的直接原因。
另外,如果目标位图与源位图的像素格式不匹配,方法内部会重新创建目标位图的缓冲区,进一步导致原有内容丢失。
解决方案
要实现在原有位图上叠加复制指定区域的效果,不要使用CopyFromBitmap(),改用TCanvas.DrawBitmap()方法,它可以保留目标位图的原有内容,仅将源区域绘制到目标位置。
修改后的代码示例
unit testUnit; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Objects, FMX.Controls.Presentation, FMX.StdCtrls; type TForm1 = class(TForm) Image1: TImage; Image2: TImage; Button1: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.fmx} procedure TForm1.Button1Click(Sender: TObject); var srcRect, destRect: TRectF; begin // 源位图中要复制的区域(FMX推荐使用TRectF浮点坐标) srcRect := TRectF.Create(50, 50, 100, 100); // 目标位图中的绘制位置与大小 destRect := TRectF.Create(100, 150, srcRect.Width + 100, srcRect.Height + 150); // 使用Canvas.DrawBitmap实现叠加复制 Image1.Bitmap.Canvas.BeginScene; try Image1.Bitmap.Canvas.DrawBitmap(Image2.Bitmap, srcRect, destRect, 1); finally Image1.Bitmap.Canvas.EndScene; end; end; procedure TForm1.FormCreate(Sender: TObject); begin Image1.Bitmap.SetSize(300, 300); Image1.Bitmap.Canvas.BeginScene; try Image1.Bitmap.Canvas.Clear($FFFF00); finally Image1.Bitmap.Canvas.EndScene; end; Image2.Bitmap.SetSize(300, 300); Image2.Bitmap.Canvas.BeginScene; try Image2.Bitmap.Canvas.Clear($FF00FF); finally Image2.Bitmap.Canvas.EndScene; end; end; end.
补充说明
- 如果一定要使用
CopyFromBitmap(),需要先将目标位图的内容临时保存到另一个位图,复制完成后再合并临时内容与新复制的内容,但这种方式步骤繁琐,远不如DrawBitmap()高效简洁。 - FMX框架的
TBitmap在跨平台(如Android)上的行为和VCL有明显差异,需要注意区分两种框架的API设计逻辑。
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

